web-dev-qa-db-fra.com

Comment utiliser TransactionScope en C #?

J'essaie d'utiliser TransactionScope, mais continuez à recevoir l'exception ci-dessous.
L'application fonctionne sur une machine différente de la base de données, si cela est important. J'utilise SQL Server 2005.

L'accès au réseau pour Distributed Transaction Manager (MSDTC) a été désactivé. Veuillez activer DTC pour l'accès au réseau dans la configuration de sécurité pour MSDTC à l'aide de l'outil d'administration des services de composants.

using (TransactionScope tsTransScope = new TransactionScope())
{
    //Do stuff here
    tsTransScope.Complete();
}

Modifier

J'ai apporté quelques modifications en fonction des commentaires. Maintenant, je reçois cette erreur:

"L'erreur HRESULT E_FAIL a été renvoyée d'un appel à un composant COM."
"La communication avec le gestionnaire de transactions sous-jacent a échoué."

Solution Je pense que la réponse acceptée a résolu le problème initial que j'obtenais. La 2e erreur semble être spécifique à Entity Framework. Je posterai une autre question pour cela.

Voici les propriétés du client:
Client http://www.portnine.com/data/images/Misc/client.jpg

Voici les propriétés sur le serveur:
Serveur http://www.portnine.com/data/images/Misc/server.jpg

37
NotDan

Vous devez activer l'accès DTC réseau comme décrit dans ce Article Microsoft TechNet . Cette modification peut devoir être effectuée à la fois sur la base de données et sur les serveurs d'applications. Souvent, DTC est déjà activé sur un serveur de base de données, je regarde donc d'abord le serveur d'applications.

Voici une capture d'écran de ce que nous utilisons, à l'exception de l'option "Autoriser l'administration à distance": Security Configuration Screenshot

Je n'ai pas rencontré le problème HRESULT E_Fail que vous rencontrez maintenant, mais cet article sur XP SP2 et transactions avait cette suggestion intéressante:

Un autre paramètre de configuration que vous devez connaître (bien que je considère qu'il s'agit d'un scénario inhabituel) est la clé de registre RestrictRemoteClients. Si la valeur de cette clé est définie sur 2 (RPC_RESTRICT_REMOTE_CLIENT_HIGH), les transactions réseau MSDTC ne pourront pas fonctionner correctement. MSDTC prend en charge uniquement les valeurs RPC_RESTRICT_REMOTE_CLIENT_NONE (0) et RPC_RESTRICT_REMOTE_CLIENT_DEFAULT (1). Voir http://www.Microsoft.com/technet/prodtechnol/winxppro/maintain/sp2netwk.mspx#XSLTsection12812112012 pour plus d'informations sur RestrictRemoteClients.

Enfin, bien qu'il ne soit pas spécifique à votre problème, une chose très importante à noter à propos de l'utilisation de la classe TransactionScope est que son paramètre par défaut est d'utiliser un Transaction Isolation Level of Serializable . Sérialisable est le plus restrictif des niveaux d'isolement et franchement il est surprenant qu'il ait été choisi par défaut. Si vous n'avez pas besoin de ce niveau de verrouillage, je recommande fortement de définir le niveau d'isolement sur une option moins restrictive (ReadCommitted) lors de l'instanciation d'un TransactionScope:

var scopeOptions = new TransactionOptions();
scopeOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
scopeOptions.Timeout = TimeSpan.MaxValue;

using (var scope = new TransactionScope(TransactionScopeOption.Required,
    scopeOptions))
{
    // your code here
}
33
ahsteele

Panneau de configuration - Outils d'administration - Services de composants - Propriétés du Poste de travail - Onglet MSDTC - Onglet Configuration de la sécurité - Accès DTC réseau (coché)/Autoriser les clients distants (coché)/Autoriser les entrants (coché)/Autoriser les sortants (coché)/Activer les transactions TIP ( vérifié)

Redémarrer l'ordinateur.

3
Otávio Décio

Selon le backend que vous utilisez, TransactionScope nécessite souvent d'activer le gestionnaire de transactions distribuées. Certains détails sont sur ce blog MSDN .

De plus, si vous utilisez plusieurs ressources, le DTC peut être requis. L'activation de DTC peut être nécessaire dans votre situation, ou vous assurer que vous utilisez SQL Server 2005 et que vous vous en tenez à ce qui serait faisable dans les transactions légères.

2
Reed Copsey

Vous devez activer DTC pour l'accès réseau dans la configuration de sécurité pour MSDTC à l'aide de l'outil d'administration des services de composants.

1
Mia Clarke

Si vous utilisez SQL Server 2000, System.Transactions.TransactionScope entraînera la promotion de toutes les transactions en transactions distribuées, nécessitant l'exécution de MS Distributed Transaction Coordinator.

Vous pouvez résoudre ce problème en démarrant le service MSDTC, en effectuant une mise à niveau vers SQL Server 2005 ou en implémentant quelque chose comme ma solution de projet de code: http://www.codeproject.com/KB/database/typed_dataset_transaction.aspx

Je n'ai jamais eu besoin de le faire, mais vous devriez également vérifier la réponse d'Ocdecio pour configurer également les paramètres de sécurité réseau pour DTC.

0
Neil Barnwell

Vous devez activer l'accès réseau DTC pour le serveur de base de données et le serveur sur lequel l'application s'exécute.

Vous devrez également vérifier que les connexions ne seront pas bloquées par un pare-feu. Étant donné qu'une connexion sera établie à partir du serveur de base de données vers la machine d'application, il est également important d'ajouter MSDTC à la liste des exceptions de pare-feu sur la machine d'application.

0

J'ai eu le même problème lors de l'exécution des tests d'intégration.

J'ai posté une question à ce sujet ici

mais finalement j'ai trouvé un moyen de contourner cela. Cependant, je ne recommanderais pas de faire cela pour le code de production. Je le faisais dans le cadre de tests.

0
Joseph