Conditionally start Saga
我有两种类型的事件:
- 人已改变
- 人员地址已更改。
当一个新的人(和一个新地址)被创建(创建或更新的种类)时,它们也会被发布。
当创建一个新人时,会发布两个事件:PersonChanged 和 PersonAddressChanged(按此顺序)。但是,由于
我想为 PersonAddressChanged 事件编写一个处理程序:
在 PersonChanged 事件中,我需要将人员插入数据库,找到 saga 并再次运行 PersonAddressChanged 的??处理程序。
我可以通过 NServiceBus Sagas 实现这一目标吗?我不能假设消息处理应该按顺序进行
我同意@carlpett 关于重新思考您的活动的一些语义的声明。
我还建议您在这里考虑与传奇不同的解决方案。
如果你的 PersonAddressChanged 消息处理程序,当它发现数据库中没有当前人员时,就去创建一个具有它获得的地址的人?
你可以用 sagas 做到这一点,是的,虽然你可能不应该这样做。首先,对于创建和更新人员具有相同的事件会丢失事件中的语义信息(这是您试图通过检查数据库中的用户来重新创建的内容)。你也会让自己暴露在很多潜在的竞争条件下,并且需要考虑如何处理它们。我的建议是重新设计您的消息流,这可能会让您当前的问题消失。
但是,如果你想尝试一下,你会做这样的事情:(未经测试或编译,只是概念代码)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public class MySaga : Saga<MySagaDataType>, IAmStartedByMessage<PersonChanged>, IAmStartedByMessage<PersonAddressChanged> { public override void ConfigureHowToFindSaga() { // How to correlate PersonChanged and PersonAddressChanged messages } public void Handle<PersonChanged>(PersonChanged msg) { Insert(msg); if(Data.PendingAddressChange != null) UpdateDatabase(msg); MarkAsComplete(); } public void Handle<PersonAddressChanged>(PersonAddressChanged msg) { if(IsInDatabase(msg.Person)) { UpdateDatabase(msg); MarkAsComplete(); } else { Data.PendingAddressChange = msg; } } } public class MySagaDataType : IContainSagaData { public PersonAddressChanged PendingAddressChange { get; set; } } |
如果
相反,我会依靠重试逻辑来处理乱序到达的消息。
每当处理
到再次重新处理时,