在django 1.5天内,如果我想手动管理交易(或交易中的交易),我会做这样的事情:
@transaction.commit_manually
def my_method():
master_sid = transaction.savepoint()
for item in things_to_process:
inner_sid = transaction.savepoint()
# Make changes, save models, etc.
...
if I_want_to_keep_this_iterations_changes:
transaction.savepoint_commit(inner_sid)
else:
transaction.savepoint_rollback(inner_sid)
if I_want_to_keep_all_un_rolled_back_changes_from_loop:
transaction.savepoint_commit(master_sid)
else:
transaction.savepoint_rollback(master_sid)
如果我正确理解the Django docs,升级到Django 1.6+时,我应该将上面的内容更改为:
def my_method():
transaction.set_autocommit(False)
try:
# Same code as above
finally:
transaction.set_autocommit(True)
但是,在Django 1.6+中,如果在autocommit为False时调用model.save(),Django将引发以下错误:
TransactionManagementError:最外层的'原子'块无法使用 自动提交关闭时,savepoint = False。
那么,如何在autocommit为false时保存模型? 我的旧Django 1.5代码的现代替代品是什么?
答案 0 :(得分:4)
您应该使用 transaction.atomic():
def my_method():
with transaction.atomic():
for item in things_to_process:
with transaction.atomic():
# Make changes, save models, etc.
...
if I_want_to_roll_back_this_iterations_changes:
raise Exception('inner rollback')
if I_want_to_roll_back_changes_from_loop:
raise Exception('mater rollback')
transaction.atomic()将处理提交和回滚,它可以嵌套。
答案 1 :(得分:-1)
您应该阅读controlling transactions explicitly。
特别
如果您在回滚发生之前尝试运行数据库查询,Django将引发TransactionManagementError。当与ORM相关的信号处理程序引发异常时,您可能还会遇到此行为。
和
关闭自动提交时,您可以使用原子。它只会使用保存点,即使对于最外面的块,如果使用savepoint = False声明最外面的块,它也会引发异常。