87 votes

Une instruction using peut-elle annuler une transaction de base de données si une erreur se produit ?

J'ai une IDbTransaction dans une instruction using mais je ne suis pas sûr qu'elle sera annulée si une exception est levée dans une instruction using. Je sais qu'une instruction using impose l'appel de Dispose()... mais quelqu'un sait-il s'il en va de même pour Rollback() ?

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

Mon code ressemble à 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 votes

Bonjour, juste pour clarifier le cas du "commit". Il est bien sûr obligatoire car, le using(){} appelle simplement la méthode Dispose(). La classe Transaction.Dispose ne pourrait pas savoir si elle doit Commit ou Dispose si le Commit était aussi automatique :)

0 votes

107voto

ssg Points 20321

La méthode Dispose de la classe transactionnelle effectue un rollback alors que la classe Oracle ne le fait pas. Donc, du point de vue de la transaction, cela dépend de l'implémentation.

El using pour l'objet de connexion, d'autre part, fermerait la connexion à la base de données ou renverrait la connexion au pool après l'avoir réinitialisée. Dans les deux cas, les transactions en cours doivent être annulées. C'est pourquoi une exception ne laisse jamais traîner une transaction active.

Aussi, oui, vous devriez appeler Commit() explicitement.

1 votes

Il le fera, je l'ai même testé une fois en lançant explicitement une exception.

0 votes

C'est génial ! Une question qui me vient à l'esprit maintenant est de savoir si je dois explicitement appeler commit... ou si l'instruction using s'en chargera aussi efficacement, rendant mon instruction commit actuelle superflue.

1 votes

Ce est génial, mais est-ce que cela fonctionne pour d'autres implémentations d'IDbTransaction si vous l'utilisez pour la compatibilité inter-bases ?

19voto

jhale Points 699

Vous devez appeler commit. L'instruction using ne commet rien pour vous.

8 votes

Oui, l'utilisation appellera Dispose à la sortie, qui appellera Rollback, et non Commit.

6voto

Tommy Hui Points 1055

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

0 votes

Oui, c'est ce que j'ai compris. Une transaction vit jusqu'à ce qu'un commit soit appelé ou que la connexion se termine. À ce moment-là, le journal des transactions est effectivement mis à jour avec les changements ou annulé dans le cas d'une connexion fermée (vous savez que vous n'obtiendrez jamais un commit d'une connexion fermée ;)).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X