Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NServiceBus: Aren't MSMQ Transactions BAD?

I am learning about NServiceBus and MSMQ. I was told that transactional queues in MSMQ are BAD and using them is really bad for performance. Does anyone know why? I am guessing this comes from the notion that it uses DTC and everyone knows that the DTC is not really a scalable solution. It seems to me that there are a couple of reasons that MSMQ with NServiceBus is not all that bad, but I don't know if I understand how it works completely. Looking at this logically, I can think of 3 places where NServiceBus might use transactions in order to get guaranteed delivery:

  1. When sending a message across the network, you might want to use a transaction to ensure that the message has gotten to the remote queue before you discard it.
  2. When reading a message from a local queue, you might want to make sure that it is handled successfully before discarding it.
  3. When publishing a message to multiple subscribers, you might want to make sure that it reaches ALL of them before discarding it. (I really hope this is NOT what NServiceBus does)

Can anyone set me straight as to how NServiceBus does this?

like image 268
skb Avatar asked Aug 18 '10 18:08

skb


2 Answers

Msmq transactions do not guarantee that the receiver has received the message. The transaction guarantees that the message has been received by the msmq infrastructure on your machine, and if the message is durable (the default in NSB) this means that it has been persisted on disk and will survive a restart. The message will then be delivered by msmq without blocking the caller. This is better known as "store and forward"

  1. By default MSMQ only guarantees that your local msmq infrastructure has received the message. No requirement that the receiving servers are online. This can be enabled though(see the answer from John below)

  2. This is IMO one of the key selling points of NSB. The ability to use transactions that spans both the local queue and your datastore (Ie distributed transaction) is crucial to guarantee consistency. Ie if something fails nothing is persisted in your data store and the message is rolled back and retried without the user having to do anything.

  3. Same as #1. The only guarantee is that each subscriber will eventually receive the published message. No blocking calls are made so as long you have free disk space and the publishing server the call will return immediately.

Hope this helps!

like image 191
Andreas Öhlund Avatar answered Oct 18 '22 12:10

Andreas Öhlund


Point #2 is correct. You don't want a message to cause an error and then fall through the cracks. You want the message handler to succeed, in which case it is removed from the queue, or to fail and be rolled back, so that it can either be retried or sent to an error queue for analysis after a configurable number of retries has been reached.

like image 45
David Boike Avatar answered Oct 18 '22 12:10

David Boike