2009-03-13 2 views
69

J'ai une IDbTransaction dans une instruction using mais je ne sais pas si elle sera annulée si une exception est levée dans une instruction using. Je sais qu'une instruction using imposera l'appel de Dispose() ... mais est-ce que quelqu'un sait si la même chose est vraie pour Rollback()?Une instruction using annulera-t-elle une transaction de base de données si une erreur se produit?

Mise à jour: Aussi, dois-je appeler Commit() explicitement comme je l'ai ci-dessous ou sera-t-il également pris en charge par l'instruction using?

Mon code ressemble un peu comme ceci:

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

Salut, juste pour clarifier le cas "commit". Il est bien sûr obligatoire car, using() {} appelle simplement la méthode Dispose(). La classe Transaction.Dispose ne pouvait pas savoir si elle devait Commit ou Dispose si la validation était également automatique :) –

+0

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

Répondre

85

Apparemment oui (pour SQL Server). Voici comment la méthode Dispose de SqlInternalTransaction (qui Éliminez de SqlTransaction appelle) ressemble de Reflector:

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

EDIT: @Medinoc mentionné que OracleConnection ne le fait pas il semble donc la mise en œuvre spécifique.

+0

Je le testerai même une fois en lançant explicitement une exception. –

+0

C'est génial! Une question dans mon esprit est de savoir si je dois appeler explicitement commit ... ou si l'instruction using gérera celle-ci de manière trop efficace pour rendre mon instruction de validation actuelle redondante. – mezoid

+1

Cela * est * génial, mais cela fonctionne-t-il pour d'autres implémentations d'IDbTransaction si vous l'utilisez pour une compatibilité cross-db? –

4

Je crois que s'il y a une exception telle que Commit() n'a jamais été appelée, alors la transaction sera automatiquement annulée.

+0

Ouais c'est ma compréhension. Une transaction reste active jusqu'à ce qu'une validation soit appelée ou que la connexion se termine. À ce stade, le journal des transactions est réellement mis à jour avec les modifications ou annulé dans le cas d'une connexion fermée (vous savez que vous ne recevrez jamais de validation d'une connexion fermée;)). – Mike

17

Vous devez appeler validation. L'instruction using ne commettra rien pour vous.

+5

Oui, l'utilisation appellera Dispose à la sortie, qui appellera Rollback, pas Commit. – awe

Questions connexes