了解Vaughn Vernon的最终一致性,BacklogItem和Tasks示例

时间:2017-11-01 14:12:36

标签: rabbitmq domain-driven-design domain-events

我很难理解如何使用Vaughn Vernon的BacklogItems和Tasks的暴露示例来实现最终一致性。到目前为止我已经理解的声明是(考虑他将BacklogItem和Task拆分为单独的聚合根的情况):

  

BacklogItem可以包含一个或多个任务。当BacklogItem的任务中的所有剩余小时数为0时,BacklogItem的状态应更改为“DONE”

我知道规则说你不应该在同一个事务中更新两个聚合根,并且你应该通过最终的一致性来实现它。

域服务更新任务的小时数后,应将TaskRemainingHoursUpdated事件发布到与执行代码位于同一线程中的DomainEventPublisher。在这里,我对以下问题感到茫然:

  • 我认为应该有一个订阅者(我也想生活在同一个帖子中)应该对TaskRemainingHoursUpdated个事件作出反应。您在桌面/ Web应用程序中的哪个位置执行此总线订阅?在你的应用程序的初始化?在应用程序代码中?有没有理由在特定的地方放置域名下标?
  • 该下标(在同一个线程中)是否应该调用BacklogItem存储库并执行更新? (但这违反了不在同一事务中更新两个聚合的规则,因为这会同步发生,对吗?)。
  • 如果你想实现最终的一致性以完成前面提到的规则,我是否真的需要像RabbitMQ这样的Message Broker,即使BacklogItem和Task都在同一个Bounded Context中?
  • 如果我使用这个消息代理,我是否应该有后台线程或者只是从RabbitMQ队列中消耗事件然后调度事件来更新产品?

如果有人能够清楚地了解这一点,我会很感激,因为它的完整性非常复杂。

1 个答案:

答案 0 :(得分:1)

首先,你需要认识到,如果BacklogItem是否是“完成”的权威,那么它需要拥有为自己计算的所有信息。 / p>

所以BacklogItem中的某个地方是跟踪它知道哪些任务的数据,以及这些任务的已知状态。换句话说,BacklogItem有关于任务的过时副本

这是“最终一致”的一点;我们正在尝试安排系统,以便BacklogItem边界中数据的缓存副本包含对任务状态的新更改。

这反过来意味着我们需要向BacklogItem发送一个命令,告知它任务的变化。

从积压项目的角度来看,我们并不关心命令的来源。例如,我们可以将其设为手动过程“完成任务后,单击此按钮以通知待办事项”。

但是为了我们用户的理智,我们更有可能安排一个事件处理程序运行:当你看到任务的输出时,将它转发到相应的积压项目。

  

您在桌面/ Web应用程序中的哪个位置执行此总线订阅?在应用程序初始化时?

这似乎很合理。

  

该下标(在同一个线程中)是否应该调用BacklogItem存储库并执行更新? (但这违反了不在同一事务中更新两个聚合的规则,因为这会同步发生,对吧?)。

相同的线程和相同的交易不是必然重合。它可以在同一个线程中协调;但是让后果在后台发生可能更有意义。在它们的核心,事件和命令只是消息 - 写入消息,将其放入收件箱,让下一个线程担心处理。

  

如果你想实现最终的一致性来完成前面提到的规则,我真的需要像RabbitMQ这样的Message Broker,即使BacklogItem和Task都在同一个Bounded Context中吗?

没有;管道的力学根本不重要。