NserviceBus发送后回滚

NserviceBus rollback after sending

你好,我有这个代码

 SendMessageToMyQueue();
UpdateStatusInDbThatMessageWasSent();

有时在更新状态之前处理消息,我想避免这种情况。

我的问题是,如果我用这样的事务来包装那两行:

using(var tr = new TransactionScope())
{
  SendMessageToMyQueue();
UpdateStatusInDbThatMessageWasSent();
tr.Compleate();
}

将保证在 MyQueue 上创建一个锁,并且在 UpdateStatusInDbThatMessageWasSent 更新状态之前不会释放此锁?

另外,如果我添加带有回滚的 try catch 并且更新状态失败,消息会从 MyQueue 中删除吗?

队列上没有锁这样的东西。但是,如果满足以下条件,则将以事务方式处理该消息。通过事务,我的意思是如果抛出未处理的异常,消息将返回到队列。实现这一目标的条件是:

  • 您的数据库可以登记并参与分布式事务。不是每个数据库都有。一些文档数据库对 DTC 有 none(在 MongoDB 的情况下)或粗略的(在 RavenDB 的情况下)支持。

  • 您的传输还支持分布式事务。如果您使用代理类型的传输,SQL 服务器传输是您最好的选择,而在总线类型的传输上,MSMQ 是一个不错的选择。 Azure ServiceBus 或 RabbitMQ 等传输对事务的支持非常有限,不支持分布式事务。

  • 您需要 运行 配置分布式事务处理协调器服务并 运行 宁。

还有两点需要注意:

  • 如果您使用的传输不支持 DTC 怎么办?大多数时候,如果您可以将您的系统设计为 idempotent. Outbox NServiceBus 的功能,您可以在某种程度上模拟 DTC。

  • 当一条消息由于异常从队列中被挑选、处理并返回到队列时,它可能最终位于队列中的不同位置。设计基于消息的架构时需要design for messages arriving out of order

综上所述,exactly-once delivery guarantees一直是热门话题和争议。