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无论如何,感谢您的反馈和提供更全面答案的机会。 |
|
|
|
|
|