解决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 字典(Dictionary)操作详解
Mar 11 Python
Python导出DBF文件到Excel的方法
Jul 25 Python
django之常用命令详解
Jun 30 Python
CentOS 7下Python 2.7升级至Python3.6.1的实战教程
Jul 06 Python
Django  ORM 练习题及答案
Jul 19 Python
python调用接口的4种方式代码实例
Nov 19 Python
python求一个字符串的所有排列的实现方法
Feb 04 Python
Python 面向对象部分知识点小结
Mar 09 Python
Python Tkinter实例——模拟掷骰子
Oct 24 Python
python中字符串的编码与解码详析
Dec 03 Python
Pygame Draw绘图函数的具体使用
Nov 17 Python
python 判断文件或文件夹是否存在
Mar 18 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常用函数小技巧
2008/09/11 PHP
从零开始学YII2框架(五)快速生成代码工具 Gii 的使用
2014/08/20 PHP
thinkPHP+ajax实现统计页面pv浏览量的方法
2017/03/15 PHP
php格式文件打开的四种方法
2018/02/24 PHP
use jscript List Installed Software
2007/06/11 Javascript
javascript 写类方式之六
2009/07/05 Javascript
Extjs EditorGridPanel中ComboBox列的显示问题
2011/07/04 Javascript
jQuery 绑定事件到动态创建的元素上的方法实例
2013/08/18 Javascript
js调用css属性写法
2013/09/21 Javascript
一个很有趣3D球状标签云兼容IE8
2014/08/22 Javascript
jQuery的内容过滤选择器学习教程
2016/04/18 Javascript
javascript日期比较方法实例分析
2016/06/17 Javascript
Angular的$http与$location
2016/12/26 Javascript
微信小程序开发(一) 微信登录流程详解
2017/01/11 Javascript
JavaScript选取(picking)和反选(rejecting)对象的属性方法
2017/08/16 Javascript
JS基于for语句编写的九九乘法表示例
2018/01/04 Javascript
JS 实现获取验证码 倒计时功能
2018/10/29 Javascript
vue刷新页面时去闪烁提升用户体验效果的实现方法
2018/12/10 Javascript
jQuery设置下拉框显示与隐藏效果的方法分析
2019/09/15 jQuery
[50:20]DOTA2上海特级锦标赛主赛事日 - 5 总决赛Liquid VS Secret第四局
2016/03/06 DOTA
[47:12]TFT vs Secret Supermajor小组赛C组 BO3 第三场 6.3
2018/06/04 DOTA
Python中的XML库4Suite Server的介绍
2015/04/14 Python
Python实现SMTP发送邮件详细教程
2021/03/02 Python
python和pywin32实现窗口查找、遍历和点击的示例代码
2020/04/01 Python
python 下载文件的几种方法汇总
2021/01/06 Python
pandas针对excel处理的实现
2021/01/15 Python
css3编写浏览器背景渐变背景色的方法
2018/03/05 HTML / CSS
Shop Apotheke瑞士:您的健康与美容网上商店
2019/10/09 全球购物
衰败城市英国官网:Urban Decay英国
2020/04/29 全球购物
英文留学推荐信范文
2014/01/25 职场文书
《只有一个地球》教学反思
2014/02/14 职场文书
运动会通讯稿150字
2014/02/15 职场文书
《飞向蓝天的恐龙》教学反思
2014/04/09 职场文书
汽车技术服务与贸易专业求职信
2014/07/20 职场文书
离婚财产分隔协议书
2014/10/23 职场文书
2015年秋季小学开学典礼主持词
2015/07/16 职场文书