Azure 服务总线事务发件箱模式的替代方案

Ale*_*ksG 2 transactions consistency azure azureservicebus entity-framework-core

假设我有一个通用的传奇场景(给定三个不同的微服务 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
Run Code Online (Sandbox Code Playgroud)

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

如果我没记错的话,这就是事务发件箱模式旨在解决的问题。

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

  • EF核心
  • Azure 服务总线

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

我见过很多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();
}
Run Code Online (Sandbox Code Playgroud)

Sea*_*man 5

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

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

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

  • 在这种情况下,此链接可能会有所帮助:https://docs.pspecial.net/nservicebus/outbox/ (2认同)