【问题标题】:Django nested transactions - “with transaction.atomic()”Django 嵌套事务 - “with transaction.atomic()”
【发布时间】:2014-03-27 13:12:50
【问题描述】:

我想知道我是否有这样的事情:

def functionA():
    with transaction.atomic():
        #save something
        functionB()

def functionB():
    with transaction.atomic():
        #save another thing

有人知道会发生什么吗?如果functionB失败了,functionA也会回滚吗?

谢谢!

【问题讨论】:

  • 记住,你也可以使用@transaction.atomic 装饰器。

标签: django transactions nested atomic


【解决方案1】:
with transaction.atomic(): # Outer atomic, start a new 
          
     transaction.on_commit(foo)
     try:
       with transaction.atomic(): # Inner atomic block, create a savepoint
           transaction.on_commit(bar)
           raise SomeError() # Raising an exception - abort the savepoint
     except SomeError:
pass
# foo() will be called, but not bar()

【讨论】:

    【解决方案2】:

    是的,它会的。不管嵌套如何,如果一个原子块被异常it will roll back退出:

    如果代码块成功完成,则将更改提交到数据库。如果出现异常,则回滚更改。

    还要注意,外部块中的异常会导致内部块回滚,并且可以捕获内部块中的异常以防止外部块回滚。文档解决了这些问题。 (或查看here 了解有关嵌套事务的更全面的后续问题)。

    【讨论】:

    • “可以捕获内部块中的异常以防止外部块回滚”这部分似乎与“避免在原子内部捕获异常!”的做法相冲突。 docs.djangoproject.com/en/3.0/topics/db/transactions/…
    • @JialinZou:没有冲突。如果您阅读文档中的该部分,您将看到对捕获数据库错误的“正确方法”的引用,其示例涉及在内部块中捕获异常。他们试图警告您注意的是捕获异常并尝试在中断状态下继续进行事务。正确的做法是将内部代码用atomic()包裹起来,以确保在继续之前回滚损坏的数据库操作。
    • 感谢您的澄清!这很有帮助。
    猜你喜欢
    • 1970-01-01
    • 2017-08-25
    • 2017-07-24
    • 2015-04-26
    • 2020-08-28
    • 2015-11-11
    • 2016-09-09
    • 2014-12-12
    • 2016-09-10
    相关资源
    最近更新 更多