2013-12-02 3 views
7

Я уже привык к старым транзакциям.com.com_on_success и transaction.commit_manual с Django < 1.6. Но теперь с Django 1.6 старый API заменяется главным образом транзакционным.атомным.Django 1.6 и nesting "with 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_second_function_successful вызывается из a_first_function успешно и создает/сохраняет объекты из моделей. Сразу после того, как эта функция 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() 

Спасибо,

ответ

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.

Смежные вопросы