Search code examples
nservicebus

NserviceBus rollback after sending


Hi I have with this code

 SendMessageToMyQueue();
UpdateStatusInDbThatMessageWasSent();

that sometimes message is processed before status is updated which I would like to avoid.

My question is if I wrap that two line with a transaction like this:

using(var tr = new TransactionScope())
{
  SendMessageToMyQueue();
UpdateStatusInDbThatMessageWasSent();
tr.Compleate();
}

will be guaranteed that there will be a lock on MyQueue created and this lock will be not released until UpdateStatusInDbThatMessageWasSent will update the status?

also if I add try catch with rollback and updating status fails, will the message be removed from MyQueue ?


Solution

  • There is no such thing as lock on a queue. The message, however, will be processed transactionally, if the following conditions are met. By transactionally, I mean that the message will be returned to the queue if an unhandled exception is thrown. The conditions to make this happen are:

    • Your database can enlist and take part in a distributed transaction. Not every database out there does. Some Document databases have none (in case of MongoDB) or sketchy (in case of RavenDB) support for DTC.

    • Your transport also supports distributed transactions. If you go with a broker type transports, SQL Server Transport is your best bet and on Bus type transports MSMQ is a good choice. Transports like Azure ServiceBus or RabbitMQ have very limited transactions support and do not support distributed transactions.

    • You'll need to run Distributed Transaction Coordinator service configured and running.

    Two other things to note:

    • What if you're using a transport that lacks DTC support? Most of the time, you are better off if you can design your system to be idempotent. Outbox feature of NServiceBus allows you simulate DTC to some extent.

    • When a message is picked from the queue, processed, and returned to the queue due to an exception, it might end up being in a different place in the queue. You need to design for messages arriving out of order when designing a message-based architecture.

    With all said above, exactly-once delivery guarantees are always a hot topic and disputed.