2011-08-26 2 views
0

J'ai un problème avec EF et le traitement des transactions.EF Transactions MSDTC?

Je suis en train de le faire:

using(TransactionScope scope = new TransactionScope()) 
{ 
    using(MyEntities model = new MyEntities()) 
    { 
    MyT thing = new MyT{ Value1 = "bla", Value2 = "bla2", Value3 = "foo" }; 
    model.MyT.AddObject(thing); 
    model.SaveChanges(); 

    thing.Value4 = Service.Call("bar"); 

    // this call causes an exception in MSDTC 
    model.SaveChanges(); 

    scope.Complete(); 
    } 
} 

La raison pour laquelle je fais c'est parce que je veux faire un insert dans la db si MyT a un identifiant unique que je passto le service quand je fais l'appel je reçois alors un ref et un statut uniques du service dépeignant ce qui s'est passé pendant l'appel que j'ai alors besoin d'ajouter à l'enregistrement. D'après ce que je comprends, au cours d'une même transaction, vous ne pouvez mettre à jour qu'une seule fois un enregistrement/faire un appel d'insertion mais vous ne pouvez pas faire les deux car cela crée un problème pour une raison quelconque expliqué une raison logique pourquoi cela n'a pas pu être fait (probablement lié à un verrou).

Donc, mon problème est de savoir comment contourner cela, mais assurez-vous qu'en cas de défaillance de l'un de ces appels, je peux toujours revenir en arrière.

+0

Quelle est votre question? Comment fonctionne le code que vous avez affiché? ça me va bien. –

+0

Quelle est l'exception? – JNappi

+0

L'exception est une exception com + qui lit simplement "l'exception s'est produite dans un objet com +" c'est-à-dire ... rien dans les journaux des événements qui n'aide pas non plus. – War

Répondre

0

Essayez de créer TransactionScope avec des options de transaction. Dans les options de transaction, spécifiez ReadUncommitted.

http://msdn.microsoft.com/en-us/library/system.transactions.isolationlevel.aspx

http://msdn.microsoft.com/en-us/library/ms149853.aspx

+0

Ce n'était pas exactement sur place mais en creusant plus loin, j'ai trouvé que le problème était que le code en question ne pouvait pas être inclus dans une transaction en raison de la portée des appels en question. Autrement dit, j'utilise m propre mécanisme transactionnel. – War

1

Lorsque vous effectuez plusieurs connexions à la db à l'intérieur de la portée de la transaction, la transaction passe de transaction locale à transaction distribuée, sauf si vous utilisez explicitement la même connexion à la base de données. Lorsque la transaction est promue, elle a besoin du service MSDTC pour gérer la transaction. Si ce service n'est pas disponible, une exception sera générée.

Quelque chose comme ceci:

using(TransactionScope scope = new TransactionScope()) 
{ 
    using(MyEntities model = new MyEntities()) 
    { 
    model.Connection.Open(); 
    MyT thing = new MyT{ Value1 = "bla", Value2 = "bla2", Value3 = "foo" }; 
    model.MyT.AddObject(thing); 
    model.SaveChanges(); 

    thing.Value4 = Service.Call("bar"); 

    // this call shouldn't cause anymore an exception in MSDTC 
    model.SaveChanges(); 

    scope.Complete(); 
    } 
} 
+0

Le service est en cours d'exécution mais cela entraîne alors d'autres complications car il décide qu'il va donner une exception com + avec littéralement rien de valeur dans les journaux ou donné bac dans l'exception. – War

+1

Il est plus efficace d'éviter d'utiliser MSDTC lorsque vous le pouvez, essayez explicitement de définir la connexion pour l'éviter. – TrymBeast

+0

Une autre variante de la promotion MSDTC est l'ouverture et la fermeture d'une connexion plusieurs fois au sein d'une transaction (même si je pensais que cela avait été corrigé dans les versions plus récentes du framework). Essayez de réutiliser la connexion ouverte et de la fermer uniquement à la fin de la transaction. –

Questions connexes