Publishing Events From Web Application: Migrating From MSMQ/MSDTC to RabbitMQ and Outbox

In our API controller methods we have the following pattern:

  • write data to mongodb
  • bus.publish a message

After reading the Publishing From Web Applications doc, it seems the choice of transport can greatly affect the risk of potentially losing events (aka, never publishing) as well as both db ops and transport ops being atomic.

Right now, we’re on MSMQ for our transport with MSDTC running to ensure distributed transactions. Two questions.

  • is MSMQ/MSDTC magically gluing together the db and transport transaction for me while running on the web server’s request thread? More specifically, will both db ops and transport ops atomically commit/rollback together? My guess is no.
  • we’re soon migrating to RabbitMQ and Outbox. Based on only Outbox only working in the context of an endpoint, I’m assuming that even if #1 is magically atomic (which I’m assuming it isn’t), this approach most surely is not atomic.

The only way to make db ops in the web tier atomic using NSB that I’ve found is covered in the Outbox in an ASP.NET Core scenario post. However, this approach requires SQL Server transport to be used at the WebAPI/controller level, then NServiceBus.Router used to “bridge” between the “inside system/handler transport”. This won’t be an option for us b/c we’re 100% mongodb.

Are there any other “gotchas” waiting for me in changing MSMQ/MSDTC for Rabbit/Outbox considering the current code (write to db/dispatch message) is not going to be changed (at least not yet)?

Thanks

That’s the big one - we were in the same boat and just wound up committing the Mongo DB transaction, then sending the message. There’s a risk there of course, but we didn’t have the resources to properly implement an ASP.NET Core-compatible outbox solution. You’d basically need to roll your own outbox and dispatcher, which I’ve done before, but there’s a long tail of gotchas.

For #1, it’s been a while but transactions do get “magically” escalated in some scenarios by System.Transactions stuff.

Jimmy, I think I saw a presentation you did at an NDC conf (???) about you rolling your own outbox and dispatcher using mongodb, and it seemed like a LOT of work, esp. the rollback functionality.

Can mongodb enlist in a distributed transaction that is brokered by MSDTC? Just to be clear, these are single document/collection transactions at the db level, so the concern here isn’t a multi-document transaction, it’s if mongo can enlist in a distributed transaction along with a queue/broker that can also enlist if a distributed transaction (aka, MSMQ).

Also, when using Rabbit as NSB transport, if there is any fundamental difference between publishing and event or sending a command? At the transport level, it’s dispatching a message to either a topic or a queue, but I think the transport level transactional guarantees between those two things is the same?