Azure 服务总线替代事务性发件箱模式

Azure Service Bus alternative to transactional outbox pattern

假设我有这个通用的 saga 场景(给定三个不同的微服务 A、B 和 C,通过消息进行通信):

 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

据我了解,虽然整个工作流应该最终一致,但您希望确保本地操作(ab)在事务上保持一致以避免丢失消息(或如果反向,则避免发送消息但无法持久化操作更改)。

如果我没记错的话,这就是transactional outbox pattern要解决的问题。

在 Azure 上的 .NET 上下文中,使用

有没有办法在不将消息保存到数据库(即不使用事务发件箱)的情况下获得相同级别的事务安全性?

我看到很多 System.Transactions 提及,但它要么被用于多个数据库操作 要么 多个服务总线操作,而不是数据库和服务总线操作一起.

这样的东西能达到期望的事务一致性吗?

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();
}

不,您无法实现这一点,因为不同的资源不能参与单个事务,因为这将成为分布式事务,这在云环境中是不受欢迎的。

为确保您的数据和消息传递操作共享同一个事务,您需要研究某种持久性,例如发件箱。

NServiceBus 等框架为发件箱提供支持,使用 Azure 服务总线作为传输,SQL 服务器或文档数据库作为数据存储。