2009-04-27 7 views
3

Quelque chose d'ultra étrange se passe ici.TransactionScope timeout bizarre avec TransactionScopeOption.RequiresNew

J'ai simplement ajouté une portée de transaction autour d'un code existant que je débuggillais pour m'assurer que le fiddling que je faisais ne serait pas validé.

Cela a deux fois, puis dit:

"The transaction manager has disabled its support for remote/network transactions." 

sans aucune modification de code ou reconstruit entre le travail/nonworkingness (littéralement 3 F5S dans une rangée [application web]). Ce code local était connecté à un serveur de suppression de base de données.

Depuis ce temps, le code complètement séparé dans un projet différent expire. Si je supprime le transactionScopes de ce code il fonctionne bien, mais avec eux en place, il expire. J'ai essayé mon serveur SQL local et mes serveurs distants, tous les deux dans la transactionScope.

Qu'est-ce qui se passe?

Edit: J'ai trouvé que le changement de mes TransactionScopes de:

using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew)) 

à

using (var scope = new TransactionScope()) 

empêche le problème: s

Qu'est-ce que cela signifie?

+0

Pouvez-vous nous montrer le code s'il vous plaît ... –

+0

pas facilement, im essayant de créer un exemple simple de le reproduire. restez à l'écoute –

Répondre

0

Je crois que ce qui se passe lorsque l'erreur se produit est que l'infrastructure tente de promouvoir la transaction "légère" (c'est-à-dire DBMS) d'origine à une transaction "distribuée". Le service MSDTC (Distributed Transaction Coordinator), qui gère les transactions distribuées, ne fonctionne pas ou n'est pas en mesure de fonctionner.

Cela se produit généralement lorsqu'une transaction logique couvre deux (ou plusieurs) connexions de base de données. Bien sûr, dans votre cas, il n'y a (apparemment) qu'une seule connexion SGBD. Je suppose qu'en forçant une nouvelle portée de transaction indépendante, vous obligez également le framework à utiliser une transaction distribuée.

+0

ce gars a un problème très similaire, si cela jette plus de lumière http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework.adonet/topic62511.aspx –

3

La différence entre:

using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew)) 

et

using (var scope = new TransactionScope()) 

Est-ce que le second réutiliser la transaction existante (ambiante), alors que le premier crée une nouvelle transaction dans un ancien.

Cette transaction dans une transaction nécessite le coordinateur de transactions distribuées.

Il y a alors trois raisons probables de votre erreur:

  • Le MSDTC ne fonctionne pas
  • Votre base de données est sur une autre machine et Windows est configuré pour ne pas autoriser les transactions du réseau.
  • Votre base de données est sur une autre machine et le serveur SQL est configuré pour ne pas autoriser les transactions du réseau
+1

+1 pour souligner que " new TransactionScope() "est équivalent à" new TransactionScope (TransactionScopeOption.Required) "- cela peut faire toute la différence. – Yoopergeek

0

question ancienne mais j'ai eu le même problème alors voici les informations simples à résoudre de nombreux types de problèmes.

Si vous pouvez changer TransactionScopeOption.RequiresNew-TransactionScopeOption.Requiredvérifier si vous avez vraiment besoin d'expliciter le comportement pour les transactions imbriquées et définir explicitement le envisagez genre de champ de transaction en lisant this MSDN article. Probablement votre problème était le nombre de nouvelles transactions avec des ressources verrouillées, c'est pourquoi le problème était "bizarre".

De plus, vous devriez vérifier cette information:

The default transaction scope is considered harmful

using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew)) 

par défaut défini:

  1. IsolationLevel comme Serializable (pensez à utiliser IsolationLevel.ReadCommitted)
  2. TimeOut une minute (pensez à utiliser TransactionManager.MaximumTimeout)

Avec ces deux options et le TransactionScopeOption.RequiresNew vous devriez vous attendre à des blocages.

Voici le nouveau code:

new TransactionScope(TransactionScopeOption.Required, 
    new TransactionOptions 
    { 
     IsolationLevel = IsolationLevel.ReadCommitted, 
     Timeout = TransactionManager.MaximumTimeout 
    } 
)