2015-04-13 4 views
5

Nel Django 1.5- giorni, se volevo gestire manualmente le transazioni (o transazioni all'interno transazioni), vorrei fare qualcosa di simile:Django 1.6 - "Il blocco" atomico "più esterno non può utilizzare savepoint = False quando l'autocommit è disattivato."

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

Se ho la comprensione the Django docs correttamente, quando l'aggiornamento a Django 1.6 +, dovrei cambiare quanto sopra a qualcosa di simile:

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

Tuttavia, in Django 1.6+, se si chiama model.save() mentre autocommit è false, Django genererà il seguente errore:

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

Quindi, come faccio a salvare un modello mentre l'autocommit è falso? Qual è la sostituzione moderna per il mio vecchio codice Django 1.5?

+0

Usa @ transaction.atomic sul metodo – GrvTyagi

risposta

4

Si dovrebbe usare transaction.atomic() invece:

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() gestirà il commit e rollba ck, e può essere annidato.

Relevant docs

-1

È necessario leggere controlling transactions explicitly.

appositamente

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.

e

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.

Problemi correlati