Comprendre l’erreur
L’erreur “Communication with the underlying transaction manager has failed” se produit lorsque le service Microsoft Distributed Transaction Coordinator (MSDTC) sur une machine ne peut pas communiquer avec le service MSDTC sur une autre machine pour coordonner une transaction distribuée.
L’erreur complète et l’exception interne ressemblent généralement à ceci :
System.Transactions.TransactionManagerCommunicationException:
Communication with the underlying transaction manager has failed.
Inner Exception:
The MSDTC transaction manager was unable to pull the transaction from the
source transaction manager due to communication problems. Possible causes are:
a firewall is present and it doesn't have an exception for the MSDTC process,
the two machines cannot find each other by their NetBIOS names, or the support
for network transactions is not enabled for one of the two transaction managers.
(Exception from HRESULT: 0x8004D02B)
Cela se produit couramment lorsque :
- Une application .NET utilise
TransactionScopeentre plusieurs instances SQL Server - Une procédure stockée utilise des serveurs liés avec
BEGIN DISTRIBUTED TRANSACTION - Des services WCF utilisent des liaisons transactionnelles entre machines
Quand les transactions distribuées sont déclenchées
Vous ne réalisez peut-être pas que votre application utilise des transactions distribuées. Elles sont automatiquement escaladées dans ces scénarios :
// This creates a distributed transaction if conn1 and conn2 point to different servers
using (TransactionScope scope = new TransactionScope())
{
using (SqlConnection conn1 = new SqlConnection("Server=Server1;Database=DB1;..."))
using (SqlConnection conn2 = new SqlConnection("Server=Server2;Database=DB2;..."))
{
conn1.Open();
// Execute work on Server1
conn2.Open(); // This escalates to a distributed transaction
// Execute work on Server2
}
scope.Complete();
}
Même l’ouverture de deux connexions au même serveur peut escalader vers MSDTC dans certains cas (avant .NET 4.0 avec SQL Server 2008).
Correction étape par étape
Étape 1 : Configurer les paramètres de sécurité de MSDTC
Cela doit être fait sur les deux machines impliquées dans la transaction.
- Ouvrez les Services de composants en exécutant
dcomcnfg - Naviguez vers : Services de composants > Ordinateurs > Poste de travail > Coordinateur de transactions distribuées > DTC local
- Cliquez avec le bouton droit sur DTC local et sélectionnez Propriétés
- Allez dans l’onglet Sécurité
- Configurez les paramètres suivants :
| Paramètre | Valeur |
|---|---|
| Accès DTC réseau | Coché |
| Autoriser les clients distants | Coché |
| Autoriser les transactions entrantes | Coché |
| Autoriser les transactions sortantes | Coché |
| Authentification mutuelle requise | Voir note ci-dessous |
| Aucune authentification requise | Sélectionnez si les machines ne sont PAS dans le même domaine |
| Activer les transactions XA | Coché (si vous utilisez XA) |
| Activer les transactions SNA LU 6.2 | Laisser décoché sauf si nécessaire |
Note sur l’authentification : Si les deux machines sont dans le même domaine Active Directory, utilisez Authentification mutuelle requise. Si elles sont dans des domaines ou groupes de travail différents, utilisez Aucune authentification requise.
- Cliquez sur OK et confirmez que vous souhaitez redémarrer le service MSDTC
Étape 2 : Configurer le Pare-feu Windows
L’exception interne mentionne spécifiquement le pare-feu. Sous Windows 7, Windows Server 2008 et versions ultérieures, vous devez activer explicitement l’exception de pare-feu MSDTC, même si vous pensez l’avoir déjà fait.
Utilisation du Pare-feu Windows avec sécurité avancée
# Enable the predefined MSDTC firewall rules (do this on BOTH machines)
Enable-NetFirewallRule -DisplayGroup "Distributed Transaction Coordinator"
Ou manuellement via l’interface graphique :
- Ouvrez le Pare-feu Windows avec sécurité avancée (
wf.msc) - Cliquez sur Règles de trafic entrant
- Trouvez les règles dans le groupe Coordinateur de transactions distribuées
- Activez-les toutes (clic droit > Activer la règle) :
- Coordinateur de transactions distribuées (RPC)
- Coordinateur de transactions distribuées (RPC-EPMAP)
- Coordinateur de transactions distribuées (TCP-In)
Répétez pour les règles de trafic sortant également.
Configurer un port MSDTC fixe (recommandé pour les pare-feu)
Par défaut, MSDTC utilise des ports RPC dynamiques, ce qui rend la configuration du pare-feu difficile. Vous pouvez attribuer un port fixe :
- Ouvrez les Services de composants (
dcomcnfg) - Naviguez vers Poste de travail > Coordinateur de transactions distribuées > DTC local > Propriétés
- Il n’y a pas d’interface graphique pour le paramètre de port ; utilisez le registre :
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSDTC]
"ServerTcpPort"=dword:00001388
Cela configure MSDTC pour utiliser le port TCP 5000 (0x1388). Ensuite, créez une règle de pare-feu spécifique :
New-NetFirewallRule -DisplayName "MSDTC Fixed Port" -Direction Inbound -Protocol TCP -LocalPort 5000 -Action Allow
New-NetFirewallRule -DisplayName "MSDTC RPC" -Direction Inbound -Protocol TCP -LocalPort 135 -Action Allow
Après avoir changé le port, redémarrez le service MSDTC :
Restart-Service -Name MSDTC
Étape 3 : Vérifier la résolution de noms NetBIOS
Les deux machines doivent pouvoir se résoudre mutuellement par nom NetBIOS, pas seulement par adresse IP ou FQDN. MSDTC utilise le nom NetBIOS en interne.
Testez depuis chaque machine :
:: From the client, test resolution of the server
ping SERVER1
nbtstat -a SERVER1
:: From the server, test resolution of the client
ping CLIENT1
nbtstat -a CLIENT1
Si la résolution de noms échoue, ajoutez des entrées au fichier hosts sur les deux machines :
# C:\Windows\System32\drivers\etc\hosts
10.0.1.10 SERVER1
10.0.1.20 CLIENT1
Ou mieux, assurez-vous que WINS ou DNS avec les enregistrements appropriés est configuré.
Étape 4 : Vérifier que le service MSDTC est en cours d’exécution
# Check MSDTC service status on both machines
Get-Service -Name MSDTC | Select-Object Name, Status, StartType
# Ensure it is set to start automatically
Set-Service -Name MSDTC -StartupType Automatic
Start-Service -Name MSDTC
Étape 5 : Tester la communication MSDTC
Utilisez l’outil DTCPing de Microsoft pour tester la connectivité MSDTC entre deux machines.
- Téléchargez DTCPing depuis Microsoft
- Exécutez
dtcping.exesur les deux machines simultanément - Sur chaque machine, entrez le nom NetBIOS de l’autre machine
- Cliquez sur Ping — un test réussi affiche “successfully completed” pour les tests RPC et de transaction
Alternativement, testez depuis PowerShell :
# Test RPC endpoint mapper connectivity
Test-NetConnection -ComputerName SERVER1 -Port 135
# Test the MSDTC fixed port (if configured)
Test-NetConnection -ComputerName SERVER1 -Port 5000
Transactions distribuées avec SQL Server
Scénario : Requêtes avec serveur lié
Lorsque SQL Server exécute une requête via un serveur lié, MSDTC est impliqué :
-- This triggers a distributed transaction
BEGIN DISTRIBUTED TRANSACTION
INSERT INTO LocalDB.dbo.Orders (OrderID, CustomerName)
SELECT OrderID, CustomerName FROM [RemoteServer].RemoteDB.dbo.Orders
WHERE OrderDate > '2024-01-01';
COMMIT TRANSACTION
Assurez-vous que MSDTC est configuré sur les deux machines SQL Server.
Scénario : .NET TransactionScope
using (var scope = new TransactionScope())
{
using (var conn = new SqlConnection(connectionString1))
{
conn.Open();
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "INSERT INTO Table1 (Col1) VALUES ('Value1')";
cmd.ExecuteNonQuery();
}
}
using (var conn = new SqlConnection(connectionString2))
{
conn.Open(); // Escalates to distributed transaction
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "INSERT INTO Table2 (Col1) VALUES ('Value2')";
cmd.ExecuteNonQuery();
}
}
scope.Complete();
}
Éviter les transactions distribuées inutiles
Si les deux connexions ciblent la même instance SQL Server, vous pouvez éviter l’escalade vers MSDTC en réutilisant une seule connexion :
using (var scope = new TransactionScope())
using (var conn = new SqlConnection(connectionString))
{
conn.Open();
using (var cmd1 = conn.CreateCommand())
{
cmd1.CommandText = "INSERT INTO DB1.dbo.Table1 (Col1) VALUES ('Value1')";
cmd1.ExecuteNonQuery();
}
using (var cmd2 = conn.CreateCommand())
{
cmd2.CommandText = "INSERT INTO DB2.dbo.Table2 (Col1) VALUES ('Value2')";
cmd2.ExecuteNonQuery();
}
scope.Complete();
}
Liste de vérification pour le dépannage
Parcourez cette liste de vérification sur les deux machines :
- Le service MSDTC est en cours d’exécution et configuré en démarrage automatique
- Les paramètres de sécurité des Services de composants sont corrects (Accès DTC réseau activé, Autoriser entrantes/sortantes)
- Le Pare-feu Windows a l’exception du Coordinateur de transactions distribuées activée pour le trafic entrant et sortant
- La résolution de noms NetBIOS fonctionne dans les deux sens
- Le même niveau d’authentification MSDTC sur les deux machines (Authentification mutuelle, Authentification de l’appelant entrant, ou Aucune authentification)
- Le port RPC 135 est accessible entre les machines
- Le test DTCPing réussit dans les deux sens
- L’antivirus ne bloque pas le trafic MSDTC ou RPC
- SQL Server a l’accès distant activé (
sp_configure 'remote access', 1) - Environnements en cluster : Si SQL Server est en cluster, configurez MSDTC comme une ressource en cluster, pas seulement sur les nœuds individuels
Pièges courants
Le Pare-feu Windows « semble » ouvert mais ne l’est pas
Sous Windows 7 et Server 2008+, le pare-feu peut sembler avoir les exceptions MSDTC activées, mais les règles peuvent être appliquées au mauvais profil réseau (Domaine vs Privé vs Public). Vérifiez :
Get-NetFirewallRule -DisplayGroup "Distributed Transaction Coordinator" |
Select-Object Name, Enabled, Profile, Direction
Assurez-vous que les règles sont activées pour le bon profil.
Différentes instances MSDTC dans un cluster
Sur un cluster de basculement Windows Server, chaque instance en cluster de SQL Server doit avoir sa propre ressource MSDTC. Le MSDTC local sur le nœud peut ne pas être celui qui gère les transactions pour l’instance SQL en cluster.
Corruption du fichier journal MSDTC
Si le fichier journal MSDTC est corrompu, le service peut démarrer mais échouer lors du traitement des transactions :
:: Reset the MSDTC log
msdtc -resetlog
Résumé
L’erreur “Communication with the underlying transaction manager has failed” est un problème de configuration du pare-feu et de MSDTC. Pour la résoudre, ouvrez les Services de composants sur les deux machines et activez l’Accès DTC réseau avec Autoriser les transactions entrantes et sortantes. Ensuite, activez l’exception du Coordinateur de transactions distribuées dans le Pare-feu Windows sur les deux machines. Vérifiez que les machines peuvent se résoudre mutuellement par nom NetBIOS, et utilisez DTCPing pour valider la communication MSDTC de bout en bout.