Distributed Transactions Tweaks in NServiceBus
While using NServiceBus on the first engagement at Readify, we had an interesting configuration. Development environment has a shared database which runs on a server but when creating the backend application, we’re running NServiceBus on our local developer machines. When handling messages, NServiceBus creates an ambient transaction using MSDTC which spans multiple resources/machines and is of course a valuable feature because if an exception is thrown somewhere in your code when a message is being processed, database transactions (or any other DTC enlisted transactions for that matter) will automatically rollback so you won’t have to write boilerplate code. This was problematic for us because DTC was not enabled on the database server so we couldn’t test the application at all. We needed to tell NServiceBus not to use DTC around message consumers. You gotta love open-source projects because just by looking at the code we found out there is a property on
TransactionalTransport named SuppressDTC which exactly does that, but how to set that?
You see, NServiceBus uses IoC containers to find its components, so in this case
ITransport implementation) is created by the container, so we’d have limited access to where it is created or how it is being registered in the container and have no elegant way to set this property, but luckily we were using Castle Windsor container we could do much better with its extensibility model.
In case you don’t know, Castle Windsor allows you to tap into creation of an object using
ICommissionConcern (and a similar thing for when destroying an object). So all you needed to do to get called when an object of a certain type is created is to create a class implementing
ICommissionConcern, which has only one method to implement. You also need to plug this class in and let the container know which component type is bound to this commission concern. This is done by implementing
IContributeComponentModelConstruction interface and checking the interface or concrete type of the component that is being created. Too much said, you can see it all in one piece of code.
public class TransportTransactionConfig : IContributeComponentModelConstruction