没有CQRS的域事件和版本控制



你好,我有以下场景,我不明白如何获得最终的一致性:

  1. 用户1使用基于任务的ui修改客户名
  2. App Service调用聚合
  3. 上的操作
  4. 总线使用nservicebus
  5. 发送消息
  6. NServicebus服务死亡
  7. 用户2获得聚合并呼叫更改地址
  8. 聚合操作称为
  9. 域事件触发
  10. 消息放到总线上
  11. 汽车重新启动
  12. 消息2先收到
  13. 消息2已处理,其他有界上下文更新为新地址
  14. 消息1现在接起,但顺序错误
  15. 现在发生了什么

在13中,如果我们在事件中传递聚合的版本,会有乐观并发错误吗?

如果是,Message 1 new被应用到另一个上下文中的对象。我们如何保持一致性?

这是阻止我在我的域中应用事件的问题。欢迎大家帮忙。

基本思想是更新另一个上下文中的另一个聚合。我只是被这个的并发性技术卡住了。

在命令处理程序和命令在总线上推送的意义上,我们不使用事件源或CQRS。这只是我们希望异步发生的事件处理,因为我们有一个现有的设计,我们不希望改变。

Blair

一般情况下,您将对消息进行排队。如果他们要排队,你会得到适当的排序。如果你想使用一些不支持servicebus排序的东西,那么给你的事件添加一个序列号,这样对方就可以正确地对它们重新排序。TCP自1981年以来一直这样做http://www.ietf.org/rfc/rfc793.txt:)

哎呀:我刚刚注意到您实际上在示例中使用了2个不同的任务(客户名称,然后客户地址)。当然,这将是一个没有问题,因为顺序应该真的不重要。但我将留下我的答案,以防你的意图是有两个相同类型的变化。

总是有几个问题/问题出现在脑海中:

一方面,您的示例不需要端点失败,因为2个用户可以同时更新地址,处理的顺序可以是随机的。所以问题就变成了哪一个是正确的地址。所以解析需要更多的分析。首先,我想我们可以假设客户不会频繁移动,以至于两个用户同时更新地址(甚至在它附近)——:)

尽管如此,也许第一个地址是正确的。

我认为对于这样的场景,您需要确定并发性,甚至一些其他容忍度是否是一个问题。因此,也许一个地址可能每天只更改一次,其他任何更改都需要其他交互作用。因此,一些异常处理将是一个选项。

你真的不应该把它降到技术层面去尝试解决它,而应该看看过程/业务含义。

对于一个简单的解决方案,我会将消息发送日期与特定类型的最后操作日期相匹配。因此,当处理消息时,对于ChangeAddressCommand,您可以将其与当前的LastAddressChange进行比较,如果消息是在最后更改日期之前发送的,则拒绝它。

这里讨论NServiceBus的类似问题。OP建议使用ibus . handleccurrentmessagelater()来旋转,直到另一个消息到达。这是可行的,但可能会有问题,因为你永远不知道你要等多久。

一个更复杂的选择是使用一个saga,它将等待所有指向特定版本的消息到达。在这种情况下,排序是基于版本完成的,并且只有当聚合版本中的所有更改都发布到另一个BC时才有可能。假设Message 1对聚合的版本2进行操作。然后,它增加聚合的版本,并发布一个事件,声明它已对版本2进行了操作。消息2对聚合的版本3进行操作,并发布一个事件,声明它已对版本3进行了操作。当另一个BC中的NServiceBus端点在消息1之前接收到消息2时,它知道最后接收到的消息对聚合的版本1进行了操作,因此它需要一个对版本2进行了操作的消息。它将开启一个等待下一个消息的传奇。一旦接收到消息1,传奇将应用消息1,然后应用消息2,并释放传奇状态。如果不能接受使用版本进行测序,可以使用另一种测序策略。

根据这个你应该问自己:

失败对业务的影响是什么?

在当前的情况下,每一百万个请求出现一次这个问题。如果您接受这两个请求都是有效的,我认为对业务不会有太大的影响。

相关内容

  • 没有找到相关文章

最新更新