Jan 292009
 

“Do not anticipate trouble, or worry about what may never happen. Keep in the sunlight.” 

- Benjamin Franklin

 

It’s obvious that Mr. Franklin didn’t have to deal with bad data, bad code, or even the occasional hiccup. In the real world, there is “trouble” and we need to not only anticipate that trouble, but also worry about what may never happen. Simply “keeping in the sunlight” won’t maintain data or application state integrity. In the real world we need transactions!

Since .NET 2.0, we’ve had the privilege of using System.Transactions.TransactionScope to manage our transactions with very few headaches. One of the headaches that almost everyone experiences is MSDTC. One of the oldest and most elusive topics on the web. There are tons of blog and forum posts directing our fellow developers to check their firewall settings for every MSDTC problem. The latest MSDTC hiccup I have seen comes in the beautifully packaged error message:

The flowed transaction could not be unmarshaled. The following exception occurred: Communication with the underlying transaction manager has failed.

The what could not be what? You can read some MSDN documentation on the topic which will probably cause you more pain. If you are seeing this error message, there’s only a few things that may be wrong.

  1. MSDTC Settings
    • Check the MSDTC settings on the machine that is initiating the transaction. If “Allow Outbound” is not checked, then it won’t allow the transaction in progress to be flowed to the next machine in the transaction chain. Check the box and restart MSDTC… it should work.
  2. Un-Trusted Domains
    • I have seen this error when you are trying to flow transactions between machines that are in un-trusted domains. Machines in different domains that do not trust each other block the antiquated, yet necessary, WINS resolution between the two machines. MSDTC relies on WINS resolution. I have fixed this problem before by adding host file entries on both machines pointing to the other machine. I can’t guarantee that this will work in all cases. Both of those machines are no longer under my control.
  3. Imaged Servers
    • The most recent, and most blogged about problem is surprisingly caused by two machines created from the same image. Cloning or imaging servers is quite common. Building a server from scratch is not a fun activity, so we build one, create an image, and put that image on every server we want to build after that. Once again, MSDTC is standing in our way because of the way it detects the sending and receiving application’s unique identifier. Each machine has a GUID in the registry that identifies it uniquely as a participant in an MSDTC transaction. Imaged machines have the same GUID. I’ll talk about the detection and resolution of this for the remainder of this post.

Running DtcPing.exe between the two machines will actually tell you that the machines are using the same GUID. Output window text from DtcPing shown below.

DTCping log file: C:DTC PingTHRESHER4160.log
Firewall Port Settings:
Port:5150-5250
RPC server is ready
Please Start Partner DTCping before pinging
WARNING:the CID values for both test machines are the same
Please send following LOG to Microsoft for analysis:
Partner LOG: SCORPION6128.log
My LOG: THRESHER4160.log

Tucked away in the last step of a Microsoft Knowledge Base article titled “How to troubleshoot MS DTC firewall issues” is a reference to this problem. Use regedit.exe to look at the registry on both machines. Locate the HKEY_CLASSES_ROOTCID key in the registry.

Find your MSDTC CID in the registry

Find the CID key that has a description value of “MSDTC”. If they are the same, the transaction cannot flow.

WARNING: Back up your registry before making any changes!

Solution 1 – Replace the offending CID keys/values on one of the machines: In this case, you will need to find all keys/values with GUID 28b81f1c-2afb-4ee2-ad85-5bc62dad1647 in your registry and replace it with a new GUID (using GuidGen). There is likely to be 3 places this GUID appears. It is also important to note that the offending GUID appears in the DtcPing log file generated during the ping test.

Solution 2 – Use msdtc command line tool to re-install MSDTC: The commands are simply:

msdtc -uninstall
msdtc -install

After making the registry changes or running the msdtc command line tool, you must restart your server for the changes to take effect.