0

我正在努力理解如何使用 Vaughn Vernon 的 BacklogItems 和 Tasks 的公开示例来实现最终一致性。到目前为止我所理解的语句是(考虑到他将 BacklogItem 和 Task 拆分为单独的聚合根的情况):

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

我知道这条规则说你不应该在同一个事务中更新两个聚合根,你应该以最终的一致性来完成。

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

  • 我想应该有一个订阅者(我猜也住在同一个线程中)应该对TaskRemainingHoursUpdated事件做出反应。在您的桌面/Web 应用程序中,您在哪一点执行了对总线的订阅?在您的应用程序初始化时?在应用程序代码中?是否有任何理由将域下标放置在特定位置?
  • 该下标(在同一个线程中)是否应该调用 BacklogItem 存储库并执行更新?(但这将违反在同一事务中不更新两个聚合的规则,因为这会同步发生,对吗?)。
  • 如果你想实现最终的一致性来满足前面提到的规则,我是否真的需要像 RabbitMQ 这样的消息代理,即使 BacklogItem 和 Task 都存在于同一个限界上下文中?
  • 如果我使用这个消息代理,我应该有一个后台线程还是只使用 RabbitMQ 队列中的事件然后调度事件来更新产品的东西?

如果有人能对此有所了解,我将不胜感激,因为要完整地描绘它是相当复杂的。

4

1 回答 1

2

因此,首先,您需要认识到,如果BacklogItem它是“完成”与否的权威,那么它需要拥有所有信息来为自己计算。

因此,BacklogItem 中的某处是跟踪它所知道的任务以及这些任务的已知状态的数据。换句话说,该任务BacklogItem有一份过时的信息副本。

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

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

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

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

在您的桌面/Web 应用程序中,您在哪一点执行了对总线的订阅?在您的应用程序初始化时?

这似乎很合理。

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

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

如果你想实现最终的一致性来满足前面提到的规则,我是否真的需要像 RabbitMQ 这样的消息代理,即使 BacklogItem 和 Task 都存在于同一个限界上下文中?

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

于 2017-11-01T14:50:52.767 回答