2015-04-13 12 views
5

W Django 1.5- dzień, gdybym chciał ręcznie zarządzać transakcji (lub transakcje wewnątrz transakcji), chciałbym zrobić coś takiego:Django 1.6 - "Najbardziej zewnętrzny blok atomowy" nie może używać savepoint = False, gdy autocommit jest wyłączony. "

@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) 

Jeśli mam zrozumienia the Django docs poprawnie, podczas uaktualniania do Django 1.6 +, należy zmienić powyższe na coś takiego:

def my_method(): 
    transaction.set_autocommit(False) 
    try: 
     # Same code as above 
    finally: 
     transaction.set_autocommit(True) 

jednak w Django 1.6 +, jeśli zadzwonisz model.save() podczas AUTOCOMMIT jest false, Django podniesie się następujący błąd:

TransactionManagementError: The outermost 'atomic' block cannot use savepoint = False when autocommit is off.

Jak więc zapisać model, gdy autocommit jest fałszywy? Jaki jest współczesny zamiennik mojego starego kodu Django 1.5?

+0

Użyj metody @ transaction.atomic na metodzie – GrvTyagi

Odpowiedz

4

Należy użyć transaction.atomic() zamiast:

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() zajmie commit i rollba ck i może być zagnieżdżony.

Relevant docs

-1

Powinieneś przeczytać controlling transactions explicitly.

specjalnie

If you attempt to run database queries before the rollback happens, Django will raise a TransactionManagementError. You may also encounter this behavior when an ORM-related signal handler raises an exception.

i

You may use atomic when autocommit is turned off. It will only use savepoints, even for the outermost block, and it will raise an exception if the outermost block is declared with savepoint=False.

Powiązane problemy