RabbitMQ, atomic message and DB transaction when not in a MessageHandler

Within a REST API request that changes state in a locale database we need to send a Command as well. Does NSB provide a feature to guarantee the command is send when the transaction is committed? I thought Outbox would help me, but this is within a MessageHandler only, right?

NSB 7x + RabbitMQ

@Stig_Christensen, it’ll be available. We’re currently working on the NServiceBus.TransactionalSession package that will enable outbox-like behavior with all the supported persisters outside the context of an incoming message.

I don’t have details about its work-in-progress status at the moment.

Ok thanks. I am surprised NSB in version 7 doesn’t include this feature. How did other manage to cope without this feature? Is it straightforward to do a custom implementation?

Hi @Stig_Christensen,

If the REST API you’re building is under development, a way to handle this scenario is to delay saving the state changes in the local database. Instead, you would just send out a message as part of the REST API. When processing that message, you could store any necessary state changes and send additional messages if needed. At that point, since you’re in the context of a message handler, you can rely on the Outbox guarantees.

However, there are scenarios in which this is not feasible. We sometimes see large codebases in which this practice is not followed, at which point retroactively introducing this change is a considerable effort. This is especially true when messaging is introduced in an already running system. Sometimes there are other valid reasons for not delaying storing the data.

We’re working on filling that gap with the new package mentioned.


New REST API so under development. :slight_smile: Unfortunately this is not good enough, since the API must be transactional, and data must be stored when returning. User should see the changed data on the next API call.

It’ll be available for v7 as well, in an upcoming minor release.

No, unfortunately, it’s not. The only scenario in which it is a bit easier is if your transport is SqlTransport and you’re storing data in SqlServer. In that case, there are workarounds to enlist in the same transaction the transport uses to dispatch messages.