假设我有一个视图函数foo
调用模型方法bar
。foo
和bar
都装饰有@method_decorator(transaction.commit_manually)
。两人总是在返回之前做一个transaction.rollback()
。
这种嵌套回滚是否会按预期工作,即调用foo
时不会发生数据库更改?
(从我的测试来看,它似乎有效,但我不确定,因为我找不到适用于这种情况的 Django 事务的任何明确信息。注意我正在使用Django 1.4和PostgreSQL 9.1.4。
这里你必须小心,数据库提交/回滚是连接级别的,如果你有这样的东西:
@transaction.commit_manually
def foo():
bar()
transaction.rollback()
@transaction.commit_manually
def bar()
#some db op
transaction.commit()
#running
foo()
对数据库的更改将被提交,您应该将@transaction.commit_manual放在顶级函数上。在 django 1.6 中引入了 transaction.atomic decorator,它通常提供您正在寻找的内容:
原子块可以嵌套。在这种情况下,当内部块成功完成时,如果稍后在外部块中引发异常,其效果仍然可以回滚
另一方面,你只是进行回滚应该没问题(如果你想坚持 1.4),只要提交只在顶层,但在这种情况下最好将事务管理保持在一级(例如引发异常并在 foo()中处理它们)