2009-03-13 15 views
69

Tengo un IDbTransaction en una instrucción de uso, pero no estoy seguro si se retrotraerá si se lanza una excepción en una instrucción de uso. Sé que una declaración de uso hará cumplir la llamada de Dispose() ... pero ¿alguien sabe si lo mismo es cierto para Rollback()?¿Se usará una instrucción para deshacer una transacción de base de datos si se produce un error?

Actualización: Además, ¿tengo que llamar a Commit() explícitamente como lo he mencionado más abajo o también se ocupará de ello con la instrucción using?

Mi código es algo así como esto:

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

Hola, solo para aclarar el caso "commit". Es obviamente obligatorio porque, al usar() {} solo se llama al método Dispose(). La clase Transaction.Dispose no pudo saber si debería comprometerse o descartar si el Commit también era automático :) –

+0

Véase también http://stackoverflow.com/questions/6418992/is-it-a-better-practice-to-explicitly -call-transaction-rollback-or-let-an-except – nawfal

Respuesta

85

Al parecer sí (para SQL Server). Así es como método Dispose de SqlInternalTransaction (que disponen de SqlTransaction llama) se ve desde Reflector:

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

EDIT: @Medinoc mencionó que OracleConnection no hace eso por lo que parece implementación específica.

+0

Lo hará, incluso probé esto una vez al lanzar explícitamente una excepción. –

+0

¡Eso es increíble! Una pregunta en mi mente ahora es si necesito llamar explícitamente a commit ... o la declaración using lo manejará de manera demasiado efectiva haciendo que mi enunciado de commit actual sea redundante. – mezoid

+1

Eso * es * increíble, pero ¿funciona para otras implementaciones de IDbTransaction si lo está usando para compatibilidad cross-db? –

4

Creo que si hay una excepción como que nunca se llamó a Commit(), la transacción se revertirá automáticamente.

+0

Sí, lo entiendo. Una transacción vive hasta que se invoca una confirmación o la conexión finaliza. En ese punto, el registro de transacciones se actualiza con los cambios o se retrotrae en el caso de una conexión cerrada (usted sabe que nunca obtendrá una confirmación de una conexión cerrada;)). – Mike

17

Debes llamar al compromiso. La declaración de uso no comprometerá nada para usted.

+5

Sí, el uso llamará a Dispose al salir, que llamará Rollback, no Commit. – awe

Cuestiones relacionadas