gpt4 book ai didi

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

转载 作者:qq735679552 更新时间:2022-09-29 22:32:09 29 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章解决Django transaction进行事务管理踩过的坑由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

概要

Transaction是django进行数据库原子性操作在python层面上的实现.

简单来说, 被transaction.atomic()包裹的代码块只在代码块顺利完成后进行数据库层面的commit。实际开发当中,遇到了一些问题.

1. transaction事务内不执行数据库的commit操作

除非手动commit 。

transaction最基本的功能.

代码场景:

在事务当前启动celery异步任务, 无法获取未提交的改动.

?
1
2
3
4
5
6
7
8
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操作的事务管理 。

代码如下:

?
1
2
3
4
5
6
7
8
def example_view(request):
     tag = False
     with transaction.atomic():
         tag = True
         change_obj() # 修改对象变量
         obj.save()
         raise DataError
     print ( "tag = " ,tag)
?
1
tag = True #输出内容

即使事务代码块发生了DataError,事务回滚,也仅是数据库层面的回滚,针对python的操作依然已完成.

甚至是对Model.Object进行的操作会也会存在变量当中.

如:

?
1
2
3
4
5
6
7
8
def example_view(request):
     obj.changed = False
     with transaction.atomic():
         obj.changed = True
         change_obj() # 修改对象其他变量
         obj.save()
         raise DataError
     print ( "obj.changed = " ,obj.changed)
?
1
obj.changed = True #输出内容

发生Dataerror异常的回滚仅在数据库层面操作,因此不可以根据model object的属性值判断是否正确完成了事务.

另外,虽然Django对数据库层面以ORM完成了很具体的抽象,但应该要清楚地意识到我们操作的model object和数据库内容本质不同,DJANGO只在查询和提交时进行数据库操作.

补充:Django 事务transaction.atomic()的使用方法 。

看代码吧~

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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' )   

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

原文链接:https://blog.csdn.net/m0_37422289/article/details/82221489 。

最后此篇关于解决Django transaction进行事务管理踩过的坑的文章就讲到这里了,如果你想了解更多关于解决Django transaction进行事务管理踩过的坑的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com