1

我正在尝试 NES 0.3 (https://github.com/elliotritchie/NES),但在理解会发生什么时遇到了一些麻烦。我正在运行示例应用程序,其中我已将 EventStore 配置更改为 SQL 服务器,并在执行离开 SendMessageCommandHandler.Handle() 之前插入了一个异常。

然后我启动处理程序和网站。我创建了一个运行良好的新用户。在我的 EventStore 表中注册了一个事件。然后我尝试发送消息。由于我的异常,这失败了。因此,由于总线的事务性质,没有调度 NServiceBus 事件。但是在 EventStore 中,事件被注册并标记为dispatched=1

我错过了什么?当它没有被 NServiceBus 调度时,它肯定不应该被注册为调度吗?错误队列中的唯一消息是“SendMessageCommand”。这可能是我的理解是错误的,所以我想在向作者报告这个问题之前先在这里问一下。

4

2 回答 2

1

NES 的 0.3.0.1 版本http://nuget.org/List/Packages/NES现在只会在所有处理程序成功运行后提交任何更改。

不过,您仍然应该考虑自己管理消息幂等性。您可以通过以下几种方式做到这一点:

默认情况下,EventStore 在向数据库提交更改时会抑制任何环境事务。但是,如果您使用的是 SQL Server 或 Raven,您可以将 EventStore 的 TransactionScopeOption 更改为 Required,这将确保事务将使用 MSDTC 进行分发,并且一切都会为您处理。

使用 2PC 的替代方法是保留所有接收到的消息的日志,并使用它来接受/拒绝对特定消息的处理。这种方法的一个例子可以在这里找到:http: //blog.jonathanoliver.com/2010/04/extending-nservicebus-avoiding-two-phase-commits/

于 2011-08-28T13:43:55.920 回答
1

在底层,NES 使用 EventStore 项目。按照设计,在调用 MarkAsDispatched() 之前,不会将每个提交视为已分派。结果,我推测某些东西在一个意想不到的位置调用了该方法。

首先,您是否有一个 EventStore 实例正在运行。确保您没有运行两个实例。除此之外,我建议单步执行处理程序以找出提交被标记为已调度的位置。

于 2011-08-25T19:49:32.883 回答