Django 1.6 - "当autocommit关闭时,最外面的'atomic'块不能使用savepoint = False."

Tro*_*roy 5 django transactions

在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)
Run Code Online (Sandbox Code Playgroud)

如果我正确理解Django文档,升级到Django 1.6+时,我应该将上面的内容更改为:

def my_method():
    transaction.set_autocommit(False)
    try:
        # Same code as above
    finally:
        transaction.set_autocommit(True)
Run Code Online (Sandbox Code Playgroud)

但是,在Django 1.6+中,如果在autocommit为False时调用model.save(),Django将引发以下错误:

TransactionManagementError:当autocommit关闭时,最外面的'atomic'块不能使用savepoint = False.

那么,如何在autocommit为false时保存模型? 什么是我的旧Django 1.5代码的现代替代品?

小智 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')
Run Code Online (Sandbox Code Playgroud)

transaction.atomic()将处理提交和回滚,并且可以嵌套。

相关文档