解决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入门篇之条件、循环
Oct 17 Python
Python的装饰器模式与面向切面编程详解
Jun 21 Python
python中的字典使用分享
Jul 31 Python
Pycharm学习教程(3) 代码运行调试
May 03 Python
python中partial()基础用法说明
Dec 30 Python
python 输出所有大小写字母的方法
Jan 02 Python
python抖音表白程序源代码
Apr 07 Python
Python+PyQt5实现美剧爬虫可视工具的方法
Apr 25 Python
PyTorch中model.zero_grad()和optimizer.zero_grad()用法
Jun 24 Python
解析python 类方法、对象方法、静态方法
Aug 15 Python
python 邮件检测工具mmpi的使用
Jan 04 Python
Python爬取酷狗MP3音频的步骤
Feb 26 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
一个数据采集类
2007/02/14 PHP
php中如何判断一个网页请求是ajax请求还是普通请求
2013/08/10 PHP
jQuery动画animate方法使用介绍
2013/05/06 Javascript
JS弹出可拖拽可关闭的div层完整实例
2015/02/13 Javascript
浅谈js控制li标签排序问题 js调用php函数的方法
2016/10/16 Javascript
JS获取浮动(float)元素的style.left值为空的快速解决办法
2017/02/19 Javascript
JavaScript生成图形验证码
2020/08/24 Javascript
详解使用vscode+es6写nodejs服务端调试配置
2017/09/21 NodeJs
EasyUI框架 使用Ajax提交注册信息的实现代码
2017/09/27 Javascript
详解如何将 Vue-cli 改造成支持多页面的 history 模式
2017/11/20 Javascript
浅谈vue 单文件探索
2018/09/05 Javascript
ES6基础之 Promise 对象用法实例详解
2019/08/22 Javascript
jQuery实现轮播图效果
2019/11/26 jQuery
ant design vue 表格table 默认勾选几项的操作
2020/10/31 Javascript
[15:20]DOTA2亚洲邀请赛总决赛开幕式表演:羽泉献唱
2017/04/05 DOTA
[02:06]2018完美世界全国高校联赛秋季赛开始报名(附彩蛋)
2018/09/03 DOTA
python追加元素到列表的方法
2015/07/28 Python
Python简单生成8位随机密码的方法
2017/05/24 Python
基于Python2、Python3中reload()的不同用法介绍
2019/08/12 Python
PyCharm导入python项目并配置虚拟环境的教程详解
2019/10/13 Python
查看端口并杀进程python脚本代码
2019/12/17 Python
Python文字截图识别OCR工具实例解析
2020/03/05 Python
浅谈pandas dataframe对除数是零的处理
2020/07/20 Python
matplotlib绘制鼠标的十字光标的实现(自定义方式,官方实例)
2021/01/10 Python
探究 canvas 绘图中撤销(undo)功能的实现方式详解
2018/05/17 HTML / CSS
英国时尚运动品牌的合集:The Sports Edit
2017/12/20 全球购物
次世代生活态度:Hypebeast
2018/07/05 全球购物
YSL圣罗兰美妆英国官网:Yves Saint Laurent Beauty UK
2019/08/03 全球购物
Chi Chi London官网:购买连衣裙和礼服
2020/10/25 全球购物
最新党员思想汇报
2014/01/01 职场文书
展会邀请函范文
2014/01/26 职场文书
企业办公室岗位职责
2014/03/12 职场文书
低碳生活的宣传标语
2014/06/23 职场文书
大学生实习证明范本
2014/09/19 职场文书
求职自荐信怎么写
2015/03/04 职场文书
导游词之南京莫愁湖公园
2019/11/13 职场文书