解决Django transaction进行事务管理踩过的坑


Posted in Python onApril 24, 2021

概要

Transaction是django进行数据库原子性操作在python层面上的实现。

简单来说, 被transaction.atomic()包裹的代码块只在代码块顺利完成后进行数据库层面的commit。实际开发当中,遇到了一些问题。

1. transaction事务内不执行数据库的commit操作

除非手动commit

transaction最基本的功能。

代码场景:

在事务当前启动celery异步任务, 无法获取未提交的改动。

def example_view(request):
    with transaction.atomic():
        change_obj() # 修改对象变量
        obj.save()
        async_task.delay(obj.id)
def async_task(obj_id):
    obj = Model.objects.get(pk=obj_id)
    read_the_obj() # 读取对象信息

在使用transaction当中, Model.save()都不做commit,因此如果在transaction当中设置异步任务,使用get()查询数据库,将看不到对象在事务当中的改变.这也是实现”可重复读”的事务隔离级别,即同一个事务里面的多次查询都应该保持结果不变。

2.transaction只对数据库层的操作进行事务管理

不能理解为python操作的事务管理

代码如下:

def example_view(request):
    tag = False
    with transaction.atomic():
        tag = True
        change_obj() # 修改对象变量
        obj.save()
        raise DataError
    print("tag = ",tag)
tag = True #输出内容

即使事务代码块发生了DataError,事务回滚,也仅是数据库层面的回滚,针对python的操作依然已完成。

甚至是对Model.Object进行的操作会也会存在变量当中。

如:

def example_view(request):
    obj.changed = False
    with transaction.atomic():
        obj.changed = True
        change_obj() # 修改对象其他变量
        obj.save()
        raise DataError
    print("obj.changed = ",obj.changed)
obj.changed = True #输出内容

发生Dataerror异常的回滚仅在数据库层面操作,因此不可以根据model object的属性值判断是否正确完成了事务。

另外,虽然Django对数据库层面以ORM完成了很具体的抽象,但应该要清楚地意识到我们操作的model object和数据库内容本质不同,DJANGO只在查询和提交时进行数据库操作。

补充:Django 事务transaction.atomic()的使用方法

看代码吧~

from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic import View
from django.db import transaction   # 导入事务 
 
# 类视图 (事务,@transaction.atomic装饰器)
class MyView(View): 
    @transaction.atomic
    # transaction.atomic装饰器可以保证该函数中所有的数据库操作都在一个事务中。
    def post(self, request):
 
        # 数据库操作1。。。
        # 数据库操作2。。。        
        return HttpResponse('ok') 
 
# 类视图 (事务,保存点的使用)
class MyView2(View):
    @transaction.atomic
    def post(self, request): 
        # 设置事务保存点
        s1 = transaction.savepoint()   # 可以设置多个保存点
 
        # 数据库操作。。。
 
        # 事务回滚 (如果发生异常,就回滚事务)
        transaction.savepoint_rollback(s1)  # 可以回滚到指定的保存点
 
        # 提交事务 (如果没有异常,就提交事务)
        transaction.savepoint_commit(s1)
 
        # 返回应答
        return HttpResponse('ok')

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。如有错误或未考虑完全的地方,望不吝赐教。

Python 相关文章推荐
python 生成不重复的随机数的代码
May 15 Python
python实现在windows服务中新建进程的方法
Jun 30 Python
Python中使用platform模块获取系统信息的用法教程
Jul 08 Python
python遍历 truple list dictionary的几种方法总结
Sep 11 Python
详解python实现读取邮件数据并下载附件的实例
Aug 03 Python
python实现Zabbix-API监控
Sep 17 Python
python实现LBP方法提取图像纹理特征实现分类的步骤
Jul 11 Python
python模拟鼠标点击和键盘输入的操作
Aug 04 Python
利用Python校准本地时间的方法教程
Oct 31 Python
利用Python绘制有趣的万圣节南瓜怪效果
Oct 31 Python
安装Pycharm2019以及配置anconda教程的方法步骤
Nov 11 Python
python 微信好友特征数据分析及可视化
Jan 07 Python
pdf论文中python画的图Type 3 fonts字体不兼容的解决方案
Apr 24 #Python
Python使用UDP实现720p视频传输的操作
python通配符之glob模块的使用详解
Apr 24 #Python
Django debug为True时,css加载失败的解决方案
Apr 24 #Python
python 模块重载的五种方法
Apr 24 #Python
写一个Python脚本自动爬取Bilibili小视频
python实现图片批量压缩
Apr 24 #Python
You might like
TMDPHP 模板引擎使用教程
2012/03/13 PHP
Android ProgressBar进度条和ProgressDialog进度框的展示DEMO
2013/06/19 PHP
PHP实现的简单三角形、矩形周长面积计算器分享
2014/11/18 PHP
PHP开发中AJAX技术的简单应用
2015/12/11 PHP
Symfony2学习笔记之模板用法详解
2016/03/17 PHP
Yii框架的路由配置方法分析
2019/09/09 PHP
prototype与jquery下Ajax实现的差别
2009/09/13 Javascript
jQuery 顺便学习下CSS选择器 奇偶匹配nth-child(even)
2010/05/24 Javascript
jquery1.83 之前所有与异步列队相关的模块详细介绍
2012/11/13 Javascript
详谈jQuery操纵DOM元素属性 attr()和removeAtrr()方法
2015/01/22 Javascript
jQuery制作效果超棒的手风琴折叠菜单
2015/04/03 Javascript
javascript中clipboardData对象用法详解
2015/05/13 Javascript
javascript电商网站抢购倒计时效果实现
2015/11/19 Javascript
jquery关于事件冒泡和事件委托的技巧及阻止与允许事件冒泡的三种实现方法
2015/11/27 Javascript
浅析函数声明和函数表达式——函数声明的声明提前
2016/05/03 Javascript
js获取当前页的URL与window.location.href简单方法
2017/02/13 Javascript
Vue中的ref作用详解(实现DOM的联动操作)
2017/08/21 Javascript
AngularJS监听ng-repeat渲染完成的两种方法
2018/01/16 Javascript
vue-router项目实战总结篇
2018/02/11 Javascript
详解Vue结合后台的列表增删改案例
2018/08/21 Javascript
vue 使用自定义指令实现表单校验的方法
2018/08/28 Javascript
python练习程序批量修改文件名
2014/01/16 Python
Python中使用SAX解析xml实例
2014/11/21 Python
介绍Python的Django框架中的静态资源管理器django-pipeline
2015/04/25 Python
python时间日期函数与利用pandas进行时间序列处理详解
2018/03/13 Python
Python实现的爬虫刷回复功能示例
2018/06/07 Python
简单了解Django应用app及分布式路由
2019/07/24 Python
利用Tensorflow构建和训练自己的CNN来做简单的验证码识别方式
2020/01/20 Python
Django框架安装及项目创建过程解析
2020/09/14 Python
英国手工布艺沙发在线购买:Sofas & Stuff
2018/03/02 全球购物
jurlique茱莉蔻英国官网:澳洲天然护肤品
2018/08/03 全球购物
学生档案自我鉴定
2013/10/07 职场文书
2015年质量月活动总结报告
2015/03/27 职场文书
无故旷工检讨书
2015/08/15 职场文书
导游词之湖北武当山
2019/09/23 职场文书
浅析MongoDB之安全认证
2021/06/26 MongoDB