I spent a lot of time
troubleshooting an error from a BizTalk send port:
System.Runtime.InteropServices.COMException: The MSDTC transaction
manager was unable to push the transaction to the destination 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.
I thought I would summarize
my findings.
What is MSDTC? Microsoft
Distributed Transaction Coordinator. In a nutshell, MSDTC coordinates
transactions between the BizTalk Server and SQL Server. For instance, if you
have a polling statement in SQL that updates the database, you would not want it
to commit if the message fails to get added to the BizTalk MessageBox database.
Using MSDTC, the update call will rollback if the messagebox call fails. Without
MSDTC, there is a risk of losing messages in this scenario.
MSDTC uses NetBIOS name
resolution. This was one of the first hurdles I had to overcome as the names
were not resolving to the IP address of the servers. To troubleshoot this, an
entry was made in the hosts file to resolve the sql server NetBIOS name. No
matter what you read, this is not the preferred method of dealing with name
resolution. If the IP of the server changes, every host file would have to be
modified causing an administration nightmare
Because MSDTC uses NetBIOS resolution, not a fully qualified domain name, a way
needed to be found to resolve the 'short' name with DNS. There is a setting in
Advanced TCP/IP Settings in which you can append a suffix to the short name for
resolution. Adding [domain] to this suffix list resolved the name
resolution (http://technet.microsoft.com/en-us/library/cc959339.aspx).
When this was resolved, we ran into firewall issues.
MSDTC uses port 135 to
initiate the connection. After that, Remote Procedure Call dynamically allocates
a port between 1024 and 65535. Obviously, from a security standpoint, opening
that range of ports between servers is not suggested. There is a way to limit
the port range using registry settings. At some point, this was done on the
[biztalk server] box but was not on the BizTalk server. Changing the registry
settings requires a reboot of the BizTalk server. After that was done on dev and
the firewall was open to the new range of ports, everything worked correctly. We
currently are allocating 200 ports for MSDTC connections between biztalk and
[sql server] in development (http://support.microsoft.com/kb/250367).
The ability to turn off
MSDTC is available in the binding settings of the send port. If the
UseAmbientTransactions is set to ‘false,’ your send port will make its sql call
without using transaction coordination. This is not a solution, be careful turning this off and know that distributed transaction are not required. This would be safe if your sql call included no updates, just gets.
There are also some setting
in the Component Services->Computers->My Computer->Distributed
Transaction Coordinator->Local DTC that need to be configured. In
Properties->Security Network DTC Access needs to be checked as well as
allowing all of the inbound and outbound connections. Also, since this is cross
domain, No Authentication Required should be checked. Those settings need to
match on both servers.
1 comment:
Wait..isn't setting "No aunthentication" a security risk? Especially if this is cross domain? Do you know if there's a way to specify Auth + Encryption?
Post a Comment