在 CQRS(事件源)中,事件存储中是否需要全局序列计数器?
在尝试了解 CQRS(以及一般的 DDD)时,我遇到过这样的情况:两个事件发生在不同的聚合上,但它们的顺序具有领域含义。如果是这样,那么它们可能发生得非常接近,以至于时间戳(如我所看到的示例实现所使用的)无法区分它们,这意味着事件存储不包含域的“完整”表示,因为顺序存在模糊性事件发生的地点。
例如,域可以触发适用于 Customer
聚合的 CustomerCreatedEvent
,然后触发 Agent< 上的
CustomerAssignedToAgent
事件。 /代码> 聚合。如果 CustomerAssignedToAgent
事件发生在 CustomerCreatedEvent
之前,则该事件没有意义,但通常这两个事件都可能因一个操作而被触发,这使得时间戳可能会被触发实际上是一样的。
那么我只是在建模得很糟糕吗?是否存在跨不同聚合的事件顺序很重要的情况?或者您应该在事件存储中保留一个全局序列号,以便您可以识别事件发生的确切顺序?
In trying to get my head around CQRS (and DDD in general) I have come across situations when two events occur on different aggregates but the order of them has domain meaning. If so then they could happen so close together that a timestamp (as used by the sample implementations I have seen) cannot differentiate them, meaning the event store doesn't contain a 'complete' representation of the domain as there is ambiguity over the order in which events occurred.
As an example, the domain could fire a CustomerCreatedEvent
which applies to the Customer
aggregate, and then a CustomerAssignedToAgent
event on the Agent
aggregate. The CustomerAssignedToAgent
event doesn't make sense if it occurs before the CustomerCreatedEvent
, but typically both of these might be fired as a result of one operation which makes it likely that the timestamps would effectively be the same.
So am I just modelling things badly? Should there ever be a situation where the sequence of events across different aggregates is important? Or should you keep a global sequence number on your event store, so that you can identify the exact sequence in which events occurred?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我还在domaindrivendesign雅虎列表中找到了Greg Young的这篇文章:
I also found this post by Greg Young on the domaindrivendesign yahoo list:
总的来说,强制执行全球秩序不是一个好主意。聚合旨在形成 ACID 语义边界。
这意味着不应在一笔交易中更新两个聚合,并且没有其他方法可以强制执行全局顺序。
在您的情况下,在创建 CustomerCreatedEvent 的同时,客户应该向代理聚合发送一条消息,告诉它分配自己,这可能是有意义的。一般来说,聚合间的通信应该通过消息传递来完成。
In general it is bad idea to enforce global order. Aggregates are meant to form ACID-semantics boundaries.
This means that two aggregates should not be updated in one transaction and there is no other means of enforcing global order.
In your case it could make sense that along with creating CustomerCreatedEvent Customer should send a message to Agent aggregate telling it to assign itself. Generally inter-aggregate communication should be done via messaging.