• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    解决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')    
    

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

    您可能感兴趣的文章:
    • python django事务transaction源码分析详解
    • Django bulk_create()、update()与数据库事务的效率对比分析
    • django中使用事务及接入支付宝支付功能
    • Django框架orM与自定义SQL语句混合事务控制操作
    • django框架事务处理小结【ORM 事务及raw sql,customize sql 事务处理】
    • 使用Python的Django框架实现事务交易管理的教程
    上一篇:pdf论文中python画的图Type 3 fonts字体不兼容的解决方案
    下一篇:用python自动生成日历
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

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