Running Distributed Applications With RSB
The new article titled “Building Distributed Applications with NHibernate and Rhino Service Bus” no doubt shows one of the best implementation of a Client / Service architecture, so If you haven’t checked it out, it is a must read. The problem, however, is that in certain scenarios it may not work out of the box and you need additional configuration on your client / server to make it work.
The problem is more related to how transactions are handled in Rhino Service Bus (RSB) where it uses ambient transactions along with NHibernate. The distributed transactions, if you are not familiar with, are a kind of transaction that may span multiple machines, services and operations. We’ve had this since dawn of .NET 2.0 that provided TransactionScope class. The problem with this is that MSDTC manages transactions over the network and if corporate firewall blocks the calls or the network port is blocked or for any other reason, it just won’t work. What makes it even worse is that MSDTC is disabled by default on Windows 2003 onwards and that gives me the idea that it may not be even safe to open it, but that is mind feed for another post. Let’s see how we can make it work.
This is only a problem in case you are running your database and backend service on different machines.
To see the problem in action, get the sources of Alexandria application and compile. It comes with two tiers: A client which is a WPF application, and a backend which is a console application running RSB. To see the problem I’m talking about, instead of running the BackEnd application on the same machine as your database server, try running in on another machine. After firing up setting up the configurations and running the client, it seems nothing is happening and client is stuck at loading data. The problem is an exception that is thrown and caught by the backend service and RSB just waits a few seconds and retries so it seems client recieves no answer from the bus.
If you place a break-point on a Query on backend source code, you’ll see that ISession has a problem opening a connection.
The error message says: The partner transaction manager has disabled its support for remote/network transactions. The error message is crytic but since it mentions transaction manager, I guessed it was related to MSDTC configuration, and it is. To change the configuration do the following:
- Go to Administrative Tools -> Component Services
- Open Component Services -> Computers -> My Computer
- Right click the “My Computer” node and select “Properties”
- Choose “MSDTC” tab
- Click “Security Configuration” button
In this dialog, change your settings like the following picture and restart the server (Not the service) for the changes to take effect.
Now you’d be able to run the client and backend on separate machines since MSDTC should now allow incomming and outgoing connections.
If after doing all these steps still you’re still unable to run the client and service, there is a small diagnostic tool from Microsoft named DTCPing which might help you.