解决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代码真的很爽
Aug 26 Python
Python struct模块解析
Jun 12 Python
Python判断字符串与大小写转换
Jun 08 Python
python实现自动重启本程序的方法
Jul 09 Python
Python外星人入侵游戏编程完整版
Mar 30 Python
Python实现删除列表中满足一定条件的元素示例
Jun 12 Python
python 判断网络连通的实现方法
Apr 22 Python
Python反射和内置方法重写操作详解
Aug 27 Python
对python3中pathlib库的Path类的使用详解
Oct 14 Python
python调用外部程序的实操步骤
Mar 04 Python
Python对HTML转义字符进行反转义的实现方法
Apr 28 Python
Python selenium如何打包静态网页并下载
Aug 12 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
php实现保存submit内容之后禁止刷新
2014/03/19 PHP
PHP的APC模块实现上传进度条
2015/10/27 PHP
PHP实现递归目录的5种方法
2016/10/27 PHP
PHP封装的简单连接MongoDB类示例
2019/02/13 PHP
某页码显示的helper 少量调整,另附js版
2010/09/12 Javascript
基于jquery的点击链接插入链接内容的代码
2012/07/31 Javascript
提取jquery的ready()方法单独使用示例
2014/03/25 Javascript
js判断浏览器是否支持html5
2014/08/17 Javascript
14个有用的Jquery技巧分享
2015/01/08 Javascript
JavaScript使用指针操作实现约瑟夫问题实例
2015/04/07 Javascript
jQuery实现非常实用漂亮的select下拉菜单选择效果
2015/11/06 Javascript
跟我学习javascript的prototype,getPrototypeOf和__proto__
2015/11/17 Javascript
javascript html实现网页版日历代码
2016/03/08 Javascript
利用Angularjs和bootstrap实现购物车功能
2016/08/31 Javascript
Bootstrap基本组件学习笔记之面板(14)
2016/12/08 Javascript
原生JS实现图片翻书效果
2017/02/16 Javascript
JavaScript中常见的八个陷阱总结
2017/06/28 Javascript
sharp.js安装过程中遇到的问题总结
2020/04/02 Javascript
Paypal支付不完全指北
2020/06/04 Javascript
python+pyqt实现12306图片验证效果
2017/10/25 Python
手把手教你从PyCharm安装到激活(最新激活码),亲测有效可激活至2089年
2020/11/25 Python
python实现登录与注册系统
2020/11/30 Python
Myprotein台湾官方网站:全球领先的运动营养品牌
2018/12/10 全球购物
夏威夷咖啡公司:Hawaii Coffee Company
2019/09/19 全球购物
瑞典网上购买现代和复古家具:Reforma
2019/10/21 全球购物
新加坡鲜花速递/新加坡网上花店:Ferns N Petals
2020/08/29 全球购物
DIY手工制作经营店创业计划书
2014/02/01 职场文书
元旦晚会邀请函
2014/02/01 职场文书
小学优秀辅导员事迹材料
2014/05/11 职场文书
2014年卫生监督工作总结
2014/12/09 职场文书
停电通知范文
2015/04/16 职场文书
2015年惩防体系建设工作总结
2015/05/22 职场文书
养成教育工作总结
2015/08/13 职场文书
祝福语集锦:送给闺蜜的生日祝福语
2019/10/08 职场文书
position:sticky 粘性定位的几种巧妙应用详解
2021/04/24 HTML / CSS
教你用Python+selenium搭建自动化测试环境
2021/06/18 Python