0

I have an IMessageSession and I would like to know if it's possible to make sending/publishing messages part of a transaction? e.g. would the following work?

using (var scope = new TransactionScope())
{
  // Some task that may or may not succeed
  
  await _messageSession.Send(new Message());
  scope.Complete();
}

From what I can tell the message is sent immediately, and sometimes the completion of the transaction is still happening while the message is being handled - so if it is possible then what I'm doing above is wrong.

It's part of a web page, so I don't have access to an IMessageHandlerContext where the above code works as expected

Carl
  • 1,782
  • 17
  • 24

2 Answers2

0

That depends on if the transport selected supports transaction scopes. In general it is not advised to do this.

Did you consider sending a single message and have all relevant logic processed in a handler outside of the webpage/website?

Ramon Smits
  • 2,482
  • 1
  • 18
  • 20
0

The default .NET behavior is that a TransactionScope does NOT flow with async code. In order to let your TransactionScope flow with async code, you need to create it as follows:

using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
  // Some task that may or may not succeed
  
  await _messageSession.Send(new Message());
  scope.Complete();
}

Particular has a nice Blog Post about this.

But there is no need to create a transactionscope yourself in your handlers. You can configure NServiceBus to automatically wrap all your message handlers in a TransactionScope via configuration, like this:

endpointConfiguration.UnitOfWork().WrapHandlersInATransactionScope();

See the NServiceBus UnitOfWork Documentation for more information.

Marc Selis
  • 833
  • 12
  • 17