【问题标题】:Django 1.6 and nesting "with transaction.atomic()"Django 1.6 和嵌套“with transaction.atomic()”
【发布时间】:2013-12-02 21:26:32
【问题描述】:

多年来,我已经习惯了使用 Django

After reading the docs on the new API,我仍然不确定以下代码将如何提交到数据库:

def a_first_function():
    with transaction.atomic():
        a_second_function_successful()
        a_third_function_fails()

def a_second_function_successful():
    with transaction.atomic():
        do_something()

def a_third_function_fails():
    do_something_wrong()

在此示例中,假设从 a_first_function 调用的 a_second_function_successful 成功并从模型创建/保存对象。在这个 second_function 成功后,立即调用第三个函数并失败。

鉴于使用上下文管理器的 transaction.atomic 在第一个和第二个函数中都使用了,在 a_second_function_successful 中创建/修改的数据会发生什么。它会被提交到数据库吗?它会从第一个函数自动回滚吗?我的经验是,无论如何都会提交第二个函数,但是,我希望它不会被提交。

如果第三个函数定义如下,现在会有什么不同吗:

@transaction.atomic
def a_third_function_fails():
    do_something_wrong()

或作为:

def a_third_function_fails():
    with transaction.atomic():
        do_something_wrong()

谢谢,

【问题讨论】:

    标签: django django-models transactions django-database


    【解决方案1】:

    好吧,我会说,如果您没有任何尝试,除了块来捕获触发回滚的异常,那么所有内容都将被回滚,因为异常将从 a_first_function() 传播到最顶层的 with transaction.atomic(),即使它来自a_third_function_fails()

    但是,如果您要在 a_third_function_fails 中捕获异常,这意味着您还必须执行以下操作:

    def a_third_function_fails():
        try:
            with transaction.atomic():
                do_something_wrong()
        except:
            pass
    

    然后您将回滚第三个函数而不是第二个函数,因为当您从 a_third_function_fails 调用 with transaction.atomic() 时,您正在隐式创建一个保存点。

    【讨论】:

      猜你喜欢
      • 2014-03-27
      • 2017-08-25
      • 2017-07-24
      • 2020-08-28
      • 2017-04-07
      • 2015-01-12
      • 2019-09-09
      • 2019-08-28
      • 1970-01-01
      相关资源
      最近更新 更多