1
votes

Occasionally when NServiceBus picks up a message, it fails with the exception below. This causes NServiceBus to retry (up to it's configured retry limit). Sometimes one of the retries result in the message being handled successfully, but it's common for all retries to fail with the same exception. In this case, the message is routed to the error queue as expected when all retries fail.

My question is... what would cause this exception in the first place? It doesn't appear related to my message handler code, as my code doesn't appear in the stack trace.

  • NServiceBus version: 2.6.0.1504
  • OS: Windows Server 2003
  • Handler code is targeting .NET 3.5 or earlier

Here is the full exception message and stack trace:

NServiceBus.Unicast.Transport.Msmq.MsmqTransport [(null)] - Failed raising 'finished message processing' event.  System.Messaging.MessageQueueException: Cannot enlist the transaction.
     at System.Messaging.MessageQueue.SendInternal(Object obj, MessageQueueTransaction internalTransaction, MessageQueueTransactionType transactionType)
     at System.Messaging.MessageQueue.Send(Object obj, MessageQueueTransactionType transactionType)
     at NServiceBus.Unicast.Transport.Msmq.MsmqTransport.SendMsmqMessage(Message m, String destination)
     at NServiceBus.Unicast.Transport.Msmq.MsmqTransport.Send(TransportMessage m, String destination)
     at NServiceBus.Unicast.UnicastBus.SendReadyMessage(Boolean startup)
     at NServiceBus.Unicast.UnicastBus.TransportFinishedMessageProcessing(Object sender, EventArgs e)
     at NServiceBus.Unicast.Transport.Msmq.MsmqTransport.OnFinishedMessageProcessing()
1
We eventually found that this was occurring as the result of preexisting database contention problems. When our handler code encountered the problem, it threw an exception that appears to have prematurely ended the DTC transaction. This led to the above error when MSMQ couldn't enlist the unavailable transaction. I'll spare you the (embarrassing) details about why our code didn't make this more apparent in the first place. Thanks for your help!Nate Sauber

1 Answers

1
votes

I see the method NServiceBus.Unicast.UnicastBus.SendReadyMessage(Boolean startup) in your stack trace.

This tells me that your endpoint is connected to a Distributor. After all your message handlers have completed, an endpoint connected to a distributor will send the ReadyMessage back to the Distributor's control queue to say "I'm done with that work. Please send more!"

This is supposed to happen within the same transaction as the rest of your work, but apparently the MSMQ send is having trouble enlisting in that transaction. This could point to a problem with DTC. It would be interesting to know what else you have going on in your message handlers for that message type that also enlist in the transaction. You aren't manually committing or rolling anything back are you?