我需要澄清在Rebus中使用事务作用域的情况。在配置选项中,我有o.HandleMessagesInsideTransactionScope();现在,我是否需要在处理程序中使用scope = new RebusTransactionScope()使用该语句,否则我所做的设置就足够了。在处理程序中,我进行数据库事务,然后将消息发送到其他处理程序以进行进一步处理。我需要处理程序中的所有处理都是原子的,因此需要包装在事务范围中。
我只需要知道实现此目标的正确方法即可。问候Amour Rashid。
您在这里混淆了两种类型的事务范围:Rebus有自己的事务范围,可以像这样使用它:
using (var scope = new RebusTransactionScope())
{
await bus.Send(oneMessage);
await bus.Send(anotherMessage);
// no messages have been sent at this point
//
//
// but when we do this 👇 they will be sent
await scope.CompleteAsync();
}
[当您在Rebus处理程序中时,不需要使用RebusTransactionScope
,因为该处理程序将具有其自己的事务范围,该范围在您的代码完成执行后将无任何异常。
另一个事务范围是.NET的一部分。这就是您在致电时启用的功能
Configure.With(...)
.(...)
.Options(o => o.HandleMessagesInsideTransactionScope())
.(...)
这将使Rebus处理程序在System.Transactions.TransactionScope
内部执行。
(...)我需要处理程序中的所有处理都是原子的(...)
不幸的是,它永远不可能是原子的*,因为不能将排队系统和您的数据库登记在同一事务中。我的意思是,通过将您的事务提升为分布式事务,可以使用两阶段提交协议来编排提交,这样它们就可以装扮成这样,但是不幸的是,分布式事务很慢,并且会带来很多问题。
通常,由于Rebus确保“至少一次传递”消息,因此最好确保代码是幂等的。
((*)至少一般而言,它不能