解决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函数返回值实例分析
Jun 08 Python
Python之父谈Python的未来形式
Jul 01 Python
书单|人生苦短,你还不用python!
Dec 29 Python
Python实现求一个集合所有子集的示例
May 04 Python
对numpy中的transpose和swapaxes函数详解
Aug 02 Python
详解Python中is和==的区别
Mar 21 Python
OpenCV 边缘检测
Jul 10 Python
Python closure闭包解释及其注意点详解
Aug 28 Python
python列表推导和生成器表达式知识点总结
Jan 10 Python
python使用hdfs3模块对hdfs进行操作详解
Jun 06 Python
如何利用Python 进行边缘检测
Oct 14 Python
Django中使用Celery的方法步骤
Dec 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
php上传功能集后缀名判断和随机命名(强力推荐)
2015/09/10 PHP
Yii+upload实现AJAX上传图片的方法
2016/07/13 PHP
php中static和const关键字用法分析
2016/12/07 PHP
URL编码转换,escape() encodeURI() encodeURIComponent()
2006/12/27 Javascript
Javascript中Eval函数的使用说明
2008/10/11 Javascript
js 页面执行时间计算代码
2009/03/04 Javascript
由document.body和document.documentElement想到的
2009/04/13 Javascript
setTimeout的延时为0时多个浏览器的区别
2012/05/23 Javascript
jquery实现商品拖动选择效果代码(自写)
2013/05/28 Javascript
jquery动态加载js三种方法实例
2013/08/03 Javascript
javaScript 计算两个日期的天数相差(示例代码)
2013/12/27 Javascript
HTML页面登录时的JS验证方法
2014/05/28 Javascript
easyui-edatagrid.js实现回车键结束编辑功能的实例
2017/04/12 Javascript
通俗解释JavaScript正则表达式快速记忆
2017/08/23 Javascript
webpack4之SplitChunksPlugin使用指南
2018/06/12 Javascript
微信JSSDK实现打开摄像头拍照再将相片保存到服务器
2019/11/15 Javascript
python daemon守护进程实现
2016/08/27 Python
简单易懂的python环境安装教程
2017/07/13 Python
python实现顺序表的简单代码
2018/09/28 Python
Django ManyToManyField 跨越中间表查询的方法
2018/12/18 Python
Python提取特定时间段内数据的方法实例
2019/04/01 Python
python 数据库查询返回list或tuple实例
2020/05/15 Python
CSS3弹性盒模型flex box快速入门心得(必看篇)
2016/05/24 HTML / CSS
德国网上花店:Valentins
2018/08/15 全球购物
机械制造与自动化应届生求职信
2013/11/16 职场文书
浪漫婚礼主持词
2014/03/14 职场文书
博士生求职信
2014/07/06 职场文书
音乐之声音乐广播稿
2014/09/10 职场文书
自动化专业大学生职业生涯规划范文:爱拚才会赢
2014/09/12 职场文书
毕业证明模板
2015/06/19 职场文书
结婚纪念日感言
2015/08/01 职场文书
个人销售励志奋斗口号
2019/12/05 职场文书
浅谈Redis在直播场景的实践方案
2021/04/27 Redis
人民币符号
2022/02/17 杂记
数据设计之权限的实现
2022/08/05 MySQL
Python find()、rfind()方法及作用
2022/12/24 Python