azureentity-framework-coretransactionsazureservicebusconsistency

Azure Service Bus alternative to transactional outbox pattern


Let's say I have this generic saga scenario (given three distinct microservices A, B, and C, communicating with messaging):

 1. Service A
    a. Performs operation A successfully
    b. Communicates update with message A
 2. Service B (after receiving message A)
    a. Performs operation B successfully
    b. Communicates update with message B
 3. Service C (after receiving message B)
    a. Fails to perform operation B
    b. Communicates failure
 4. Service A and B performs compensating actions

It is my understanding that while the entire workflow should be eventually consistent, you want to ensure that the local operations (the a and b) are transactionally consistent to avoid losing messages (or if reverse, avoid sending messages but fail to persist operation changes).

This is the problem that the transactional outbox pattern aims to solve, if I'm not mistaken.

In the context of .NET on Azure, using

  • EF Core
  • Azure Service Bus

Is there a way to get the same level of transactional security without saving the message to the database (i.e. not using a transactional outbox)?

I've seen a lot of System.Transactions mentions, but it's either being used for multiple database operations or multiple service bus operations, not database and service bus operations together.

Could something like this achieve the desired transactional consistency?

using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
    // _dbContext.Database.EnlistTransaction(ts); <-- ?
    _dbContext.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" });
    _dbContext.SaveChanges();
    await _serviceBusSender.SendMessageAsync(new ServiceBusMessage());
    ts.Complete();
}

Solution

  • No, you can't achieve that as different resources cannot participate in a single transaction as that would become a distributed transaction, which is undesired in a cloud environment.

    To ensure your data and messaging operations share the same transaction, you'd be looking into some sort of persistence such as outbox.

    Frameworks such as NServiceBus provide support for outbox with Azure Service Bus as a transport and SQL Server or document database as a data store.