The SQL Server transport supports the following transport transaction modes:
- Transaction scope (distributed transaction)
- Transport transaction - Send atomic with receive
- Transport transaction - receive only
- Unreliable (transactions disabled)
TransactionScope mode is particularly useful as it enables
exactly once message processing with distributed transactions. However when transport, persistence, and business data are all stored in a single SQL Server catalog, it is possible to achieve
exactly-once message delivery without distributed transactions. For more details, refer to the SQL Server native integration sample.
Exactly oncemessage processing without distributed transactions can be achieved with any transport using the Outbox feature. It requires business and persistence data to share the storage mechanism but does not put any requirements on transport data storage.
In this mode, the ambient transaction is started before receiving the message. The transaction encompasses all stages of processing including user data access and saga data access.
If either the configured NServiceBus persistence mechanism or the user data access also support transactions via
TransactionScope, the ambient transaction is escalated to a distributed one via the Distributed Transaction Coordinator (DTC).
In this mode, the message is received inside a native ADO.NET transaction
There are two available options within native transaction level:
- ReceiveOnly - An input message is received using native transaction. The transaction is committed only when message processing succeeds.
- SendsAtomicWithReceive - This mode is similar to the
ReceiveOnly, but transaction is shared with sending operations. That means the message receive operation and any send or publish operations are committed atomically.
In this mode, when a message is received it is immediately removed from the input queue. If processing fails the message is lost because the operation cannot be rolled back. Any other operation that is performed when processing the message is executed without a transaction and cannot be rolled back. This can lead to undesired side effects when message processing fails part way through.