2009-03-13 10 views
69

Ho un IDbTransaction in un'istruzione using, ma non sono sicuro se verrà eseguito il rollback se viene generata un'eccezione in un'istruzione using. So che un'istruzione using imporrà la chiamata di Dispose() ... ma qualcuno sa se lo stesso vale per Rollback()?Se si verifica un errore, verrà utilizzato un rollback dell'istruzione utilizzando una transazione di database?

Aggiornamento: Inoltre, è necessario chiamare Commit() in modo esplicito come indicato di seguito o sarà anche preso in considerazione dall'istruzione using?

mio codice è un po 'come questo:

using Microsoft.Practices.EnterpriseLibrary.Data; 

... 

using(IDbConnection connection = DatabaseInstance.CreateConnection()) 
{ 
    connection.Open(); 

    using(IDbTransaction transaction = connection.BeginTransaction()) 
    { 
     //Attempt to do stuff in the database 
     //potentially throw an exception 
     transaction.Commit(); 
    } 
} 
+3

Ciao, giusto per chiarire il caso di "commit". Ovviamente è obbligatorio perché l'uso di() {} chiama semplicemente il metodo Dispose(). La classe Transaction.Dispose non può sapere se deve eseguire commit o Dispose se anche il commit è automatico :) –

+0

Vedere anche http://stackoverflow.com/questions/6418992/is-it-a-better-practice-to-explicitly -call-transaction-rollback-or-let-an-except – nawfal

risposta

85

pare sì (per SQL Server). Questo è come metodo Dispose di SqlInternalTransaction (che chiama Dispose di SqlTransaction) assomiglia da Reflector:

private void Dispose(bool disposing) 
{ 
    // ... 
    if (disposing && (this._innerConnection != null)) 
    { 
     this._disposing = true; 
     this.Rollback(); // there you go 
    } 
} 

EDIT: @Medinoc detto che OracleConnection non lo fa così sembra specifica implementazione.

+0

Lo farò, l'ho anche testato una volta facendo esplicitamente un eccezione. –

+0

È fantastico! Una domanda a mio avviso adesso è che devo chiamare esplicitamente commit ... o l'istruzione using gestisce anche quella che rende effettivamente ridondante la mia dichiarazione di commit corrente. – mezoid

+1

Questo * è * fantastico, ma funziona per altre implementazioni di IDbTransaction se lo stai usando per la compatibilità cross-db? –

4

Credo che se c'è un'eccezione tale che Commit() non è mai stata chiamata, la transazione verrà automaticamente ripristinata.

+0

Sì, questa è la mia comprensione. Una transazione dura finché non viene chiamato un commit o la connessione termina. A quel punto il log delle transazioni viene effettivamente aggiornato con le modifiche o ripristinato nel caso di una connessione chiusa (si sa che non si otterrà mai un commit da una connessione chiusa;)). – Mike

17

Devi chiamare commit. L'istruzione using non impegna nulla per te.

+5

Sì, l'utilizzo chiamerà Dispose all'uscita, che chiamerà Rollback, non Commit. – awe

Problemi correlati