Cannot enlist the Transaction

On an initial load of 60000+ files our nServiceBus handler threw an exception

NServiceBus.Unicast.Queuing.FailedToSendMessageException: Failed to send message to address: queue@machine —> System.Messaging.MessageQueueException: Cannot enlist the transaction.

Repro

No repro – no issue. Sleeping for 61 seconds caused the same exception. Complete solution for download at the end of the post.

public void Handle(DoSomethingCommand message)
{
    // wait for the timeout of 1 minute
    log.InfoFormat("Sleeping");
    Thread.Sleep(61000);
    // throws System.Messaging.MessageQueueException:
    Bus.Send<DoAnotherThingCommand>(m => { });
}

Investigation

Looks like a transaction timeout. This is what the MSDTC Transaction Statistics look like
msdtc.transaction.statistics.aborted
Every transaction is aborted.

Solution

Setting the transaction timeout for MSDTC did not solve this issue. The timeout of 0 (never timeout) still gave the exception. But thanks to Teun we’ve solved it.

Overwriting the transaction timeout in the config did the trick.

<system.transactions>
  <defaultSettings timeout="00:05:00"/>
</system.transactions>

Now the transactions succeed and the DoAnotherThingCommands are send and processed.
msdtc.transaction.statistics.commited

References

About erictummers

Working in a DevOps team is the best thing that happened to me. I like challenges and sharing the solutions with others. On my blog I’ll mostly post about my work, but expect an occasional home project, productivity tip and tooling review.
This entry was posted in Development and tagged , , . Bookmark the permalink.

4 Responses to Cannot enlist the Transaction

  1. Pingback: DTC troubles with long running transactions in NServiceBus

  2. bjolicoeur says:

    Thanks for posting! This saved me a bunch of time.

  3. Trygve Lorentzen says:

    Alternative solution (better?): Create a new TransactionScope with TransactionScope.Suppress as long as all files are loaded before the Bus.Send. See http://stackoverflow.com/questions/13386745/recursive-bus-send-with-in-a-handler-transactions-threading-tasks

    This way you can remove transaction scope on individual handlers or part of handlers. Downloading a large file from the internet, then Bus.Send(HandleDownloadedFileCommand) is an example usage.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.