在Django中嵌套手动提交的事务

时间:2014-01-15 18:45:37

标签: django transactions

假设我有一个调用模型方法foo的视图函数barfoobar都使用@method_decorator(transaction.commit_manually)进行修饰。在返回之前,两者总是会transaction.rollback()

此嵌套回滚是否会按预期工作,即调用foo时不会发生数据库更改?

(从我的测试来看,它似乎有效,但我不确定,因为我找不到任何关于适用于这种情况的Django事务的确定性。注意我正在使用带有PostgreSQL 9.1.4的Django 1.4。)< / p>

1 个答案:

答案 0 :(得分:4)

你必须小心,数据库提交/回滚是连接级别,如果你有这样的东西:

@transaction.commit_manually
def foo():
   bar()
   transaction.rollback()

@transaction.commit_manually
def bar()
   #some db op
   transaction.commit()

#running
foo()

将提交对数据库的更改,您应该将@ transaction.commit_manually放在顶级函数上。在django 1.6中引入了transaction.atomic装饰器,它通常提供你想要的东西:

  

原子块可以嵌套。在这种情况下,当内部块成功完成时,如果稍后在外部块中引发异常,则其效果仍然可以回滚

另一方面,你只需要回滚它应该没问题(如果你想坚持1.4),只要提交只在顶级,但最好将事务管理保持在一个级别case(例如,引发异常并在foo()中处理它们)