解决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实现基于多线程、多用户的FTP服务器与客户端功能完整实例
Aug 18 Python
python matlibplot绘制多条曲线图
Feb 19 Python
python去掉 unicode 字符串前面的u方法
Oct 21 Python
对json字符串与python字符串的不同之处详解
Dec 19 Python
在Python中append以及extend返回None的例子
Jul 20 Python
关于Python-faker的函数效果一览
Nov 28 Python
Python 字符串处理特殊空格\xc2\xa0\t\n Non-breaking space
Feb 23 Python
Python 从attribute到property详解
Mar 05 Python
Python3 socket即时通讯脚本实现代码实例(threading多线程)
Jun 01 Python
python如何遍历指定路径下所有文件(按按照时间区间检索)
Sep 14 Python
python 如何执行控制台命令与操作剪切板
May 20 Python
分享python函数常见关键字
Apr 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
PHP新手上路(九)
2006/10/09 PHP
php 中文和编码判断代码
2010/05/16 PHP
php使用strtotime和date函数判断日期是否有效代码分享
2013/12/25 PHP
一张表搞清楚php is_null、empty、isset的区别
2015/07/07 PHP
学习PHP的数组总结【经验】
2016/05/05 PHP
PHP自定义函数实现assign()数组分配到模板及extract()变量分配到模板功能示例
2018/05/23 PHP
jQuery $.data()方法使用注意细节
2012/12/31 Javascript
Java File类的常用方法总结
2015/03/18 Javascript
基于Jquery和CSS3制作数字时钟附源码下载(CSS3篇)
2015/11/24 Javascript
整理Javascript函数学习笔记
2015/12/01 Javascript
深入浅析search 搜索框的写法
2016/08/02 Javascript
vue2.0+vue-dplayer实现hls播放的示例
2018/03/02 Javascript
Vue封装一个简单轻量的上传文件组件的示例
2018/03/21 Javascript
vue input 输入校验字母数字组合且长度小于30的实现代码
2018/05/16 Javascript
Vue源码学习之关于对Array的数据侦听实现
2019/04/23 Javascript
[15:23]教你分分钟做大人:虚空假面
2014/10/30 DOTA
Python实现删除当前目录下除当前脚本以外的文件和文件夹实例
2015/07/27 Python
用Python的Flask框架结合MySQL写一个内存监控程序
2015/11/07 Python
Python编程实现从字典中提取子集的方法分析
2018/02/09 Python
python学生信息管理系统(完整版)
2020/04/05 Python
Python检测端口IP字符串是否合法
2020/06/05 Python
如何用Anaconda搭建虚拟环境并创建Django项目
2020/08/02 Python
pymysql模块使用简介与示例
2020/11/17 Python
美国大型的健身社区和补充商店:Bodybuilding.com
2016/09/06 全球购物
美国复古街头服饰精品店:Need Supply Co.
2017/02/22 全球购物
红色连衣裙精品店:Red Dress Boutique
2018/08/11 全球购物
为您的家、后院、车库等在线购物:Spreetail
2019/06/17 全球购物
西部世纪.net笔试题面试题
2014/04/03 面试题
一套中级Java程序员笔试题
2015/01/14 面试题
三查三看党性分析材料
2014/02/18 职场文书
领导班子四风对照检查材料
2014/09/23 职场文书
高考升学宴答谢词
2015/01/20 职场文书
自愿离婚协议书范本
2015/01/26 职场文书
幼儿园园长安全责任书
2015/05/08 职场文书
学校教师培训工作总结
2015/10/14 职场文书
分享提高 Python 代码的可读性的技巧
2022/03/03 Python