2

我有一个处理程序,其工作是获取对象列表,并为该对象列表中的每个项目发布一个事件。这可能类似于下面的代码:

Handle(PublishListMessage message) {
    foreach(var entry in message.List) {
        Bus.Publish(entry);
    }
}

我的用例是我希望 message.List.Count 很棒,因此 foreach 循环可能需要一些时间。

因此,假设我已经处理了 100 个条目对象中的 50 个,那么 Bus.Publish(entry) 由于某种原因而失败。处理程序将根据我的重试策略重试,但是,它现在将从头开始处理所有 100 个条目。

这并不理想,所以我想在某个地方坚持进步。由于我使用 MongoDB 作为持久层,我想我可以将我的 Handler 包装在 Saga 中。Saga 将跟踪所有已处理的条目,希望如果 Handler 失败,它将重试并检索 Saga 并记录它之前取得的进展。

然而,我的快速测试让我假设在 Handler 完成执行之前不会提交 Saga(在本例中为 MongoDB)。因此,对于我的用例,这没有帮助。

我的主要问题是我是否可以在 Handler 运行完成之前的某个时间点将 Saga 提交给数据库。这给了我 Saga 的其他一些好处,而我不必在每个条目都被发送到 Publishing 之后编写自己的持久性。

我的第二个问题是,如果这确实可能,我应该在这个特定的例子中这样做吗?这是对 Saga 的有效使用还是替代方法合适?

4

1 回答 1

1

为什么你认为 bus.Publish 会失败?只有当您的传输发生故障时才会发生这种情况,但在这种情况下,NServiceBus 会将断路器设置为武装状态,并且整个端点将很快关闭。在这种情况下,我会准备好整个基础设施停机,而不是回复某些数据库来保持您的进度状态。我看不出传奇对你有什么帮助。如果您真的不信任 NServiceBus 作为简单发布的基础设施组件,您可以自己将循环状态保存在简单消息处理程序中,使用与 saga 相同的标识符。例如,这可以是相关 ID。没有什么能阻止你在消息处理程序中进行数据库操作,你不需要为此而烦恼。

于 2015-04-27T18:41:08.483 回答