解决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中的类学习笔记
Sep 23 Python
python实现下载指定网址所有图片的方法
Aug 08 Python
浅谈python socket函数中,send与sendall的区别与使用方法
May 09 Python
Python基于Flask框架配置依赖包信息的项目迁移部署
Mar 02 Python
Python不使用int()函数把字符串转换为数字的方法
Jul 09 Python
python实现局域网内实时通信代码
Dec 22 Python
关于Django Models CharField 参数说明
Mar 31 Python
PyCharm2019 安装和配置教程详解附激活码
Jul 31 Python
Python利用命名空间解析XML文档
Aug 10 Python
编译 pycaffe时报错:fatal error: numpy/arrayobject.h没有那个文件或目录
Nov 29 Python
详解python3类型注释annotations实用案例
Jan 20 Python
Matlab使用Plot函数实现数据动态显示方法总结
Feb 25 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
玩转图像函数库―常见图形操作
2006/09/03 PHP
PHP程序员的技术成长规划
2016/03/25 PHP
JS之小练习代码
2008/10/12 Javascript
Cookie 注入是怎样产生的
2009/04/08 Javascript
JS操作图片(增,删,改) 例子
2013/04/17 Javascript
Javascript delete 引用类型对象
2013/11/01 Javascript
JS中多种方式创建对象详解
2016/03/22 Javascript
jQuery配合coin-slider插件制作幻灯片效果的流程解析
2016/05/13 Javascript
js/jQuery实现全选效果
2019/06/17 jQuery
vue路由拦截器和请求拦截器知识点总结
2019/11/08 Javascript
vue-cli3.0实现一个多页面应用的历奇经历记录总结
2020/03/16 Javascript
浅谈vue权限管理实现及流程
2020/04/23 Javascript
[48:21]Mski vs VGJ.S Supermajor小组赛C组 BO3 第一场 6.3
2018/06/04 DOTA
[50:38]DOTA2-DPC中国联赛 正赛 Phoenix vs CDEC BO3 第二场 3月7日
2021/03/11 DOTA
python实现井字棋游戏
2020/03/30 Python
使用python3.5仿微软记事本notepad
2016/06/15 Python
Python HTTP客户端自定义Cookie实现实例
2017/04/28 Python
TensorFlow入门使用 tf.train.Saver()保存模型
2018/04/24 Python
Python实现基于socket的udp传输与接收功能详解
2019/11/15 Python
浅谈python之自动化运维(Paramiko)
2020/01/31 Python
解决ROC曲线画出来只有一个点的问题
2020/02/28 Python
Python matplotlib修改默认字体的操作
2020/03/05 Python
Python如何生成xml文件
2020/06/04 Python
园林施工员岗位职责
2013/12/11 职场文书
班队活动设计方案
2014/01/30 职场文书
安卓程序员求职信
2014/02/28 职场文书
公司年会抽奖活动主持词
2014/03/31 职场文书
个人工作主要事迹
2014/05/08 职场文书
药店促销活动总结
2014/07/10 职场文书
关于教师节的广播稿
2014/09/10 职场文书
构建和谐校园倡议书
2015/01/19 职场文书
储备店长岗位职责
2015/04/14 职场文书
2015婚礼主持词开场白
2015/05/28 职场文书
铁人观后感
2015/06/16 职场文书
《乌鸦喝水》教学反思
2016/02/19 职场文书
HTML5页面打开微信小程序功能实现
2022/09/23 HTML / CSS