解决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 httplib,smtplib使用方法
Sep 06 Python
Python注释详解
Jun 01 Python
Python入门_条件控制(详解)
May 16 Python
Python双精度浮点数运算并分行显示操作示例
Jul 21 Python
python实现AES加密与解密
Mar 28 Python
Python列表对象实现原理详解
Jul 01 Python
linux环境中没有网络怎么下载python
Jul 07 Python
Python实现微信中找回好友、群聊用户撤回的消息功能示例
Aug 23 Python
numpy实现神经网络反向传播算法的步骤
Dec 24 Python
python解析多层json操作示例
Dec 30 Python
pytorch masked_fill报错的解决
Feb 18 Python
Pandas实现DataFrame的简单运算、统计与排序
Mar 31 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中使用redis队列操作实例代码
2013/02/07 PHP
使用PHP实现生成HTML静态页面
2015/11/18 PHP
PHP实践教程之过滤、验证、转义与密码详解
2017/07/24 PHP
php的RSA加密解密算法原理与用法分析
2020/01/23 PHP
JQuery textlimit 显示用户输入的字符数 限制用户输入的字符数
2009/05/14 Javascript
用JS写的一个TableView控件代码
2010/01/23 Javascript
javascript 鼠标拖动图标技术
2010/02/07 Javascript
JS之Date对象和获取系统当前时间详解
2014/01/13 Javascript
Javascript基础教程之比较操作符
2015/01/18 Javascript
jQuery中的Deferred和promise 的区别
2016/04/03 Javascript
一句jQuery代码实现返回顶部效果(简单实用)
2016/12/28 Javascript
JS小数转换为整数的方法分析
2017/01/07 Javascript
自制简易打赏功能的实例
2017/09/02 Javascript
微信小程序实现action-sheet弹出底部菜单功能【附源码下载】
2017/12/09 Javascript
js取0-9随机取4个数不重复的数字代码实例
2019/03/27 Javascript
js如何实现元素曝光上报
2019/08/07 Javascript
Vue项目中数据的深度监听或对象属性的监听实例
2020/07/17 Javascript
基于Vant UI框架实现时间段选择器
2020/12/24 Javascript
[13:56]DAC2018 4.5SOLO赛决赛 MidOne vs Paparazi第一场
2018/04/06 DOTA
部署Python的框架下的web app的详细教程
2015/04/30 Python
python模拟表单提交登录图书馆
2018/04/27 Python
Python根据已知邻接矩阵绘制无向图操作示例
2018/06/23 Python
Python内存读写操作示例
2018/07/18 Python
Python动态生成多维数组的方法示例
2018/08/09 Python
解决Django后台ManyToManyField显示成Object的问题
2019/08/09 Python
python进阶之自定义可迭代的类
2019/08/20 Python
python实现的读取网页并分词功能示例
2019/10/29 Python
Django用户身份验证完成示例代码
2020/04/03 Python
解决Jupyter无法导入已安装的 module问题
2020/04/17 Python
使用CSS3制作饼状旋转载入效果的实例
2015/06/23 HTML / CSS
个人近期表现材料
2014/02/11 职场文书
解除劳动合同协议书范本2014
2014/09/25 职场文书
优秀大学生申请书
2019/06/24 职场文书
MongoDB数据库常用的10条操作命令
2021/06/18 MongoDB
SpringBoot集成Redis,并自定义对象序列化操作
2021/06/22 Java/Android
div与span之间的区别与使用介绍
2021/12/06 HTML / CSS