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
据我了解,虽然整个工作流应该最终一致,但您希望确保本地操作(a
和 b
)在事务上保持一致以避免丢失消息(或如果反向,则避免发送消息但无法持久化操作更改)。
如果我没记错的话,这就是transactional outbox pattern要解决的问题。
在 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();
}
不,您无法实现这一点,因为不同的资源不能参与单个事务,因为这将成为分布式事务,这在云环境中是不受欢迎的。
为确保您的数据和消息传递操作共享同一个事务,您需要研究某种持久性,例如发件箱。
NServiceBus 等框架为发件箱提供支持,使用 Azure 服务总线作为传输,SQL 服务器或文档数据库作为数据存储。
假设我有这个通用的 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
据我了解,虽然整个工作流应该最终一致,但您希望确保本地操作(a
和 b
)在事务上保持一致以避免丢失消息(或如果反向,则避免发送消息但无法持久化操作更改)。
如果我没记错的话,这就是transactional outbox pattern要解决的问题。
在 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();
}
不,您无法实现这一点,因为不同的资源不能参与单个事务,因为这将成为分布式事务,这在云环境中是不受欢迎的。
为确保您的数据和消息传递操作共享同一个事务,您需要研究某种持久性,例如发件箱。
NServiceBus 等框架为发件箱提供支持,使用 Azure 服务总线作为传输,SQL 服务器或文档数据库作为数据存储。