解决Django transaction进行事务管理踩过的坑

 更新时间:2021年04月24日 14:31:15   作者:chrispink_yang  
这篇文章主要介绍了解决Django transaction进行事务管理踩过的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

概要

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')    

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

相关文章

  • Windows下为Python安装Matplotlib模块

    Windows下为Python安装Matplotlib模块

    这篇文章主要介绍了如何在Windows下为Python安装Matplotlib模块的方法,非常的详细,而且附上了官方的下载地址,小伙伴们操作起来应该毫无压力了。
    2015-11-11
  • Python解决走迷宫问题算法示例

    Python解决走迷宫问题算法示例

    这篇文章主要介绍了Python解决走迷宫问题算法,结合实例形式分析了Python基于二维数组的深度优先遍历算法解决走迷宫问题相关操作技巧,需要的朋友可以参考下
    2018-07-07
  • Python的条件控制 if 语句详解

    Python的条件控制 if 语句详解

    Python的 if 语句用来「控制代码」的执行,「判断条件成立」时执行一段代码,判断条件「不成立」时执行另一段代码,本文就给大家详细讲讲Python的条件控制 if 语句,需要的朋友可以参考下
    2023-08-08
  • python PyQt5中QRadioButton的详细使用教程与应用实战

    python PyQt5中QRadioButton的详细使用教程与应用实战

    PyQt5是一个跨平台的GUI工具包,用于创建具有Python绑定的Qt应用程序,在PyQt5中,QRadioButton是一个非常有用的控件,用于在用户界面上提供单选选项,本文将详细介绍QRadioButton的基本用法、常用属性和方法,需要的朋友可以参考下
    2024-08-08
  • 《与孩子一起学编程》python自测题

    《与孩子一起学编程》python自测题

    本文内容是关于《与孩子一起学编程》python自测题,大家可以跟着测试题上机测试下程序。
    2018-05-05
  • Numpy的简单用法小结

    Numpy的简单用法小结

    这篇文章主要介绍了Numpy的简单用法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • Python 通过监听端口实现唯一脚本运行方式

    Python 通过监听端口实现唯一脚本运行方式

    这篇文章主要介绍了Python 通过监听端口实现唯一脚本运行方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-05-05
  • python中数字列表转化为数字字符串的实例代码

    python中数字列表转化为数字字符串的实例代码

    先前学习过,数字和字符串都可以存储到变量当中,下面这篇文章主要给大家介绍了关于python中数字列表转化为数字字符串的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-02-02
  • Tensorflow 自带可视化Tensorboard使用方法(附项目代码)

    Tensorflow 自带可视化Tensorboard使用方法(附项目代码)

    这篇文章主要介绍了Tensorflow 自带可视化Tensorboard使用方法(附项目代码),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-02-02
  • python实现文件的备份流程详解

    python实现文件的备份流程详解

    在本篇文章中我们给大家整理了关于python实现文件的备份的详细流程步骤,有兴趣的朋友们学习下。
    2019-06-06

最新评论