我有一个处理程序,它的工作是获取对象列表,对于该对象列表中的每个项目,发布一个事件。这可能类似于下面的代码:
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的其他一些好处,而不必在每个条目被发送出去之后写下我自己的持久性。
我的第二个问题是,如果这确实可行,我应该在这个特定的例子中做到吗?这是Saga的有效用法还是适当的替代方法?
答案 0 :(得分:1)
为什么你期望bus.Publish失败?这种情况只有在您的传输出现故障时才会发生,但在这种情况下,NServiceBus会将断路器设置为待命状态,整个端点将很快关闭。在这种情况下,我会为整个基础架构做好准备,而不是回复某个数据库以保持进度状态。我不知道传奇会如何帮助你。如果您真的不信任NServiceBus作为简单发布的基础结构组件,您可以使用与用于saga的相同标识符将循环状态保存在简单消息处理程序中。例如,这可以是相关id。没有什么可以阻止你在消息处理程序中的doind数据库操作,你不需要这样的传奇。