Django 1.6和嵌套“与transaction.atomic()”

时间:2013-12-02 21:26:32

标签: django django-models transactions django-database

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

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()

谢谢,

1 个答案:

答案 0 :(得分: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

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