多年来我一直使用旧的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()
谢谢,
答案 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
时隐式创建一个保存点。