我很难理解如何使用Vaughn Vernon的BacklogItems和Tasks的暴露示例来实现最终一致性。到目前为止我已经理解的声明是(考虑他将BacklogItem和Task拆分为单独的聚合根的情况):
BacklogItem可以包含一个或多个任务。当BacklogItem的任务中的所有剩余小时数为0时,BacklogItem的状态应更改为“DONE”
我知道规则说你不应该在同一个事务中更新两个聚合根,并且你应该通过最终的一致性来实现它。
域服务更新任务的小时数后,应将TaskRemainingHoursUpdated
事件发布到与执行代码位于同一线程中的DomainEventPublisher
。在这里,我对以下问题感到茫然:
TaskRemainingHoursUpdated
个事件作出反应。您在桌面/ Web应用程序中的哪个位置执行此总线订阅?在你的应用程序的初始化?在应用程序代码中?有没有理由在特定的地方放置域名下标?如果有人能够清楚地了解这一点,我会很感激,因为它的完整性非常复杂。
答案 0 :(得分:1)
首先,你需要认识到,如果BacklogItem
是否是“完成”的权威,那么它需要拥有为自己计算的所有信息。 / p>
所以BacklogItem中的某个地方是跟踪它知道哪些任务的数据,以及这些任务的已知状态。换句话说,BacklogItem
有关于任务的过时副本。
这是“最终一致”的一点;我们正在尝试安排系统,以便BacklogItem
边界中数据的缓存副本包含对任务状态的新更改。
这反过来意味着我们需要向BacklogItem
发送一个命令,告知它任务的变化。
从积压项目的角度来看,我们并不关心命令的来源。例如,我们可以将其设为手动过程“完成任务后,单击此按钮以通知待办事项”。
但是为了我们用户的理智,我们更有可能安排一个事件处理程序运行:当你看到任务的输出时,将它转发到相应的积压项目。
您在桌面/ Web应用程序中的哪个位置执行此总线订阅?在应用程序初始化时?
这似乎很合理。
该下标(在同一个线程中)是否应该调用BacklogItem存储库并执行更新? (但这违反了不在同一事务中更新两个聚合的规则,因为这会同步发生,对吧?)。
相同的线程和相同的交易不是必然重合。它可以在同一个线程中协调;但是让后果在后台发生可能更有意义。在它们的核心,事件和命令只是消息 - 写入消息,将其放入收件箱,让下一个线程担心处理。
如果你想实现最终的一致性来完成前面提到的规则,我真的需要像RabbitMQ这样的Message Broker,即使BacklogItem和Task都在同一个Bounded Context中吗?
没有;管道的力学根本不重要。