Django 1.6和嵌套"与transaction.atomic()"

Loi*_*ros 7 django transactions django-models django-database

多年来我一直使用较旧的transaction.commit_on_success和transaction.commit_manually与Django <1.6.但是现在使用Django 1.6,旧的API主要用transaction.atomic替换.

在阅读新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()
Run Code Online (Sandbox Code Playgroud)

在此示例中,假设从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()
Run Code Online (Sandbox Code Playgroud)

或作为:

def a_third_function_fails():
    with transaction.atomic():
        do_something_wrong()
Run Code Online (Sandbox Code Playgroud)

谢谢,

j1z*_*1z0 5

嗯,我会说,如果你没有,除了阻止任何试图捕捉触发回滚于一切的异常都将被回滚,作为异常将传播到最顶层with transaction.atomic()a_first_function(),即使是募集a_third_function_fails()

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

def a_third_function_fails():
    try:
        with transaction.atomic():
            do_something_wrong()
    except:
        pass
Run Code Online (Sandbox Code Playgroud)

然后,你将有第三个功能回滚,而不是第二个功能,因为你是隐式创建的保存点,当你打电话with transaction.atomic()a_third_function_fails.