回答

收藏

Django嵌套事务-'ith transaction.atomic()'-寻求澄清

技术问答 技术问答 277 人阅读 | 0 人回复 | 2023-09-14

在Django嵌套事务中-‘ith) e5 q' R) ?' t& w1 o
transaction.atomic()’。考虑到这一点,问题是…
* H& b, _8 m9 P* R. R. adef functionA():    with transaction.atomic():        #save something        functionB()def functionB():    with transaction.atomic():        #save another thing如果functionB是否失败并回滚functionA也会回滚?6 [% ?0 F) Z  Q; Y5 G
凯文·克里斯托弗·亨利(Kevin Christopher Henry)答:是的,如果这两个功能中的任何一个出现异常,它们都会被回滚。
  a$ x/ q" S! \然后,他引用了它docs,其中指出:& e/ z9 I& a7 f6 V8 x
原子块可以嵌套。在这种情况下,当内部块成功完成时,如果后来外部块出现异常,效果仍然可以回滚。% H6 P$ a  L( q6 K) G) M  [+ Y
文档引用似乎没有解决原始问题。文档说,当INNER
  V  S) W! x9 N, V, {* PBLOCK(即functionB)如果成功完成OUTER块(即functionA)如果出现异常,其效果仍可回滚。但问题恰恰相反。问题,如果INNER块(functionB)失败,OUTER块(functionA)是否回滚?本文档引用不能解决这种情况。
2 `0 a" y- U4 Z6 ]8 G然而,在文档的底部,我们看到了这个例子…' j2 \6 s" j  Y. {3 O7 B
from django.db import IntegrityError,transaction@transaction.atomicdef viewfunc(request):    create_parent()    try:        with transaction.atomic()generate_relationships()    except IntegrityError:        handle_exception()    add_children()…此评论之后…
0 S% Y6 l! Z, B* h2 H1 [1 T即使在这个例子中generate_relationships()数据库因破坏完整性约束而出现错误,您也可以查询add_children而且来自create_parent()那里的变化依然存在。
% ]. s# S# n; x* R! @1 i  l
如果我正在阅读文档,它说被调用generate_relationships()(这类似于调用functionB原来的问题)可能会失败,并且会做出改变create_parent(),并add_children()将被提交到数据库。这似乎与凯文有关。·克里斯托弗·亨利的回答是矛盾的。
+ F! J7 \9 l# z1 w4 ]1 M我是Django和stackoverflow新手,所以我对阅读文档没有足够的信心,但这似乎与这两个答案相矛盾。我正在寻找更有经验的人来澄清。非常感谢。7 L' }; k- p0 w8 T- [- m0 L
                                                                % J; \; f9 ]$ E
    解决方案:                                                                ) {" e$ `% U. J8 B& N
                                                                以下是一些伪代码嵌套事务块和数据库操作X,Y以及Z:# |' w. d/ z& K( k$ E/ a$ R
with transaction.atomic():    X    with transaction.atomic():        Y    Z如果X如果出现异常,显然没有机会先提交所有操作。
6 I7 K( e9 |) a4 u2 Y  `/ W! s如果Y如果出现异常(你提到的问题是你提到的问题),外部块也会回滚。就其本身而言,这与嵌套事务无关,因为Python异常出现。外部块会异常退出,总会导致回滚。不管是什么原因导致异常,这都是事实。1 V" j; t1 J! I. b, _" \7 g2 G! e' {
非显而易见的情况是Z这就是为什么文的事情,这就是为什么文档特别注意。作为参考,两者X和Y将回滚:
5 V5 `* e" j5 z7 L- Y当内部块成功完成时,如果后来外部块出现异常,其效果仍可回滚。
0 a& |1 u: o2 p现在,嵌套操作引起的异常也可以捕获。7 a: t5 n  D2 e8 w
with transaction.atomic():    X    try:        with transaction.atomic():            Y    except IntgrityError:        pass    Z在这种情况下,如果Y如果出现异常,内部块会回滚(因为它退出并有异常),而外部块不会回滚(因为它没有)。" e" v+ y& x& w( s0 S3 d
这与你提到的两个答案中的任何一个都不矛盾,因为它们针对的是特定的问题(带有代码示例),不涉及捕获任何异常。
2 i, Q$ y4 R$ ^2 {! m无论如何,感谢您的反馈和提供更全面答案的机会。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则