2009-11-10 7 views
4

Dans quelles circonstances le code enveloppé dans un System.Transactions.TransactionScope peut-il encore être validé, même si une exception a été levée et que la portée la plus externe n'a jamais été appelée?Les données ont été validées bien que System.Transactions.TransactionScope.Commit() n'ait pas été appelé

Il existe une méthode de niveau supérieur enveloppée dans using (var tx = new TransactionScope()) et qui appelle des méthodes qui utilisent également TransactionScope de la même manière. J'utilise des jeux de données typés avec tableadapters associés. Se pourrait-il que les commandes de l'adaptateur ne s'enrôlent pas pour une raison quelconque? Est-ce que l'un d'entre vous sait comment on peut vérifier s'il s'enrôle dans le TransactionScope ambiant ou non?

+0

Y a-t-il une transaction imbriquée? –

+0

Eh bien, TransactionScope est imbriqué, oui. Il existe une méthode de haut niveau enveloppée dans 'using (var tx = new TransactionScope())', et qui appelle des méthodes qui utilisent également TransactionScope. –

+0

Quelle est la base de données ici? –

Répondre

7

La réponse s'est avérée être parce que je créais l'objet TransactionScopeaprès l'objet SqlConnection.

je me suis déplacé de ceci:

using (new ConnectionScope()) 
using (var transaction = new TransactionScope()) 
{ 
    // Do something that modifies data 

    transaction.Complete(); 
} 

à ceci:

using (var transaction = new TransactionScope()) 
using (new ConnectionScope()) 
{ 
    // Do something that modifies data 

    transaction.Complete(); 
} 

et maintenant ça marche! Donc, la morale de l'histoire est de créer votre TransactionScoped'abord.

+2

Il montre également la valeur du code de comptabilisation ;-p Nous avons pu le repérer pour vous; Peu importe - trié maintenant. –

+1

Oui, mais je ne pouvais pas le faire dans ce cas, car l'application est trop complexe, et je ne l'avais pas répliquée dans un exemple plus petit. –

+4

Je pense que vous pouvez d'abord créer SqlConnection (au cas où vous auriez besoin de passer à des méthodes qui utilisent toutes TransactionScope) Dans le cas où vous avez déjà une connexion existante et que vous souhaitez créer une portée de transaction, vous pouvez simplement appeler connection.ElistTransaction (Transaction.Current) dans le bloc using pour la portée – Triynko

2

Le scénario évident serait où une nouvelle transaction (RequiresNew)/null (Suppress) est explicitement spécifié - mais il y a aussi un délai d'attente/Glitch déliaison qui peut causer des connexions à manquer la transaction. Voir ce earlier post (le correctif est juste un changement de chaîne de connexion), ou full details.

+0

J'ai essayé le changement de chaîne de connexion plus tôt tout en recherchant mon problème et cela n'a pas aidé dans ce cas. Je pense que je pourrais avoir 'RequiresNew' quelque part, alors je vais jeter un coup d'oeil. –

+0

J'utilise des jeux de données typés avec des tableadapters associés. Se pourrait-il que les commandes de l'adaptateur ne s'enrôlent pas pour une raison quelconque? Savez-vous comment on pourrait vérifier si elles s'enrôlent dans le TransactionScope ambiant ou pas? –

+0

J'ai trouvé la réponse à la fin - à faire avec l'ordre que les objets de transaction et de connexion sont créés. J'ai ajouté ma réponse à ce post. –

0

Sachez comment TransactionScope fonctionne:
Il définit la propriété System.Transactions.Transaction.Current au début de l'utilisation de la portée et puis remis à la valeur précédente à la fin de l'utilisation de la portée.

La valeur précédente dépend de l'endroit où la portée est déclarée. Cela peut être dans une autre portée.


Vous pouvez modifier le code comme ceci:

using (var sqlConnection = new ConnectionScope()) 
using (var transaction = new TransactionScope()) 
{ 
    sqlConnection.EnlistTransaction(System.Transactions.Transaction.Current); 
    // Do something that modifies data 
    transaction.Complete(); 
} 

Je montre cette possibilité pour ceux qui ont leur code plus complexe et ne peut pas simplement changer le code pour ouvrir la connexion DB premier.

Questions connexes