CQRS 中的聚合间通信 + DDD +事件溯源
应该如何分离聚合根 ( AR)在基于 DDD 原则构建的环境中使用事件源聚合后端相互通信?
例如,我有一个 Facility
聚合根 (AR),它有一个工厂方法负责创建 Booking
AR。 Booking
是 Person
AR 和 Facility
AR 的时间敏感组合。一个人
只能在一个设施
中预订。
在 DDD 中,我会在 Person
中引用 Booking
,在 Facility
中引用 Person
。但是,当生成用于事件源的事件时,我认为尝试从后端处理事件反序列化会变得令人望而却步。因此,我只保留对基于值对象的唯一 ID 的引用。然而,这带来了一个新问题,当 AR 上的一个方法需要调用另一个 AR 上的另一个方法时——你如何处理这种情况?从域 AR 命中事件源存储库?
此场景的一般用例是什么?我处理这一切都是错误的吗?
How should separate aggregate roots (AR) communicate with one another in an environment built on DDD principles using an event-sourced aggregate back-end?
For instance, I have a Facility
aggregate root (AR) which has a factory method responsible for creating a Booking
AR. The Booking
is a time-sensitive combination of a Person
AR and a Facility
AR. A Person
can only be booked in a single Facility
.
In DDD, I would have held references to the Booking
in Person
, and Person
in Facility
. However, when generating events for use in event-sourcing I think that trying to handle the event deserialization from the back-end would become prohibitive. Therefore, I've taken to only holding references to the value object-based unique id's. This brings up a new problem, however, when a method on an AR needs to call another method on another AR -- how do you handle that situation? Hit the event source repository from the domain AR?
What is the general use case in this scenario? Am I approaching this all wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
聚合根边界定义了一致性边界。
在聚合内部,一致性得到保证。
外面……不是。
因此,您不应该进行跨越多个聚合的操作并且必须保持一致。
如果您需要跨越两个聚合的事务,您应该检查聚合边界。
对于聚合之外发生的事情,您应该有一个事件处理程序,它将向其他聚合发送命令。
如果聚合之间的操作逻辑更复杂,您可以定义一个流程,一个状态机,它将侦听事件并向聚合发送命令。
流程可用于定义长时间运行的事务(通过补偿而不是回滚),或根据大规模系统中发生的情况(甚至在有界上下文之间)做出业务决策。
Aggregate Root boundaries define a consistency boundary.
Inside the aggregate, consistency is guaranteed.
Outside... it's not.
So you should not have operations that spans several aggregates and have to be consistent.
If you need a transaction that spans two aggregates, you should review your aggregate boundaries.
For things that happen outside the aggregate you should have an event handler that will send a command to other aggregates.
If the logic of actions between aggregates is more complicated, you can define a process, a state machine that will listen to events and send commands to aggregates.
Processes can be used to define long running transactions (with compensation instead of rollback), or take business decisions based on what's happening in the system at a large scale (even between bounded contexts).
当使用事件源和 CQRS 时,最优雅的(至少在我看来)AR 间通信方式是消息传递。您可以查看 Ncqrs 项目(如果您是 .NET 人员,这会更容易),特别是 '消息传递'分支。这个想法是,AR 为它们处理的每种消息类型实现 IMessageHandler 接口,并且 AR 基类公开 Send 方法用于向那里发送消息。通过此 API,客户端可以调用模型行为,并且模型本身可以进行通信(在 AR 之间)。
When using Event Sourcing and CQRS the most elegant (at least in my opinion) way of inter-AR communication is messaging. You can look at Ncqrs project (it will be easier if you are a .NET guy), particularly 'Messaging' branch. The idea is, ARs implement IMessageHandler interface for every message type they handle and AR base class exposes method Send for sending there messages. By means of this API clients can invoke model behavior and model itself can communicate (between ARs).