Search code examples
transactionsnservicebus

NServiceBus "sends-atomic-with-receive" still needs the Outbox for message deduplication?


Using the transport transaction mode of sends-atomic-with-receive avoids sending out messages in the handler of an incoming message (command or event) when the handler fails for some reason. The Outbox feature of NServiceBus avoids processing the same incoming message multiple times, and thus avoids having to write idempotent handlers. My question is : does one eliminate the need for the other? It is, when using sends-atomic-with-receive, is it still useful to use the Outbox to ensure de-duplication of incoming messages?


Solution

  • Sends atomic with receive makes sure there is no real chance on ghost messages and only applies to the transport.

    In this mode it can still happen that a message is processed more-than-once.

    What if the processing of the messages is successful, now the transport commits its transaction and that fails. Your message will now be processed again so your database change will be done again but no ghost messages have been sent.

    If you want to prevent that database change to be done again you still require the outbox if that change isn't idempotent.

    Also take note that the Outbox only does transactional exact once processing, it doesn't do deduplication but due to the transactional processing only one transaction can insert the unique message identification of the processed message which indirectly results in dedupe like behavior.

    If your resources are not transactional you are still required to make your message processing idempotent. This is also still required if the resources you are accessing are not using the same storage context as the outbox and distributed transactions between these storage resources isn't allowed or not supported.

    Documentation: