domain-driven-design - 在事件溯源中如何处理一致性违规?

标签 domain-driven-design cqrs event-sourcing referential-integrity aggregateroot

首先,让我声明我是命令查询职责分离和事件溯源(消息驱动架构)的新手,但我已经看到了一些重要的设计优势。但是,仍然有一些问题我不清楚。

假设我有一个 Customer包含名为 postalAddress 的属性的类(聚合根) (Address 类的一个实例,它是一个值对象)。我也有一个 Order包含(在 OrderItem 对象和其他事物中)一个名为 deliveryAddress 的属性的类(另一个聚合根) (也是 Address 类的一个实例)和一个名为 status 的字符串属性.

客户通过发出 PlaceOrder 下订单命令,触发 OrderReceived事件。此时订单状态为"RECEIVED" .订单发货时,仓库有人发出ShipOrder命令,触发 OrderShipped事件。此时订单状态为"SHIPPED" .

业务规则之一是,如果 Customer更新他们的 postalAddress在订单发货之前(即状态仍然是 "RECEIVED" ), deliveryAddressOrder对象也应该更新。如果状态为Order已经"SHIPPED" , deliveryAddress不会更新。

问题 1. 将这种“有条件的级联地址更新”放在 Saga(又名流程管理器)中的最佳位置是什么? 我假设是这样,因为它正在将一个事件(“客户刚刚更新了他们的邮政地址......”)转换为一个命令(“......所以更新订单 123 的送货地址”)。

问题 2. 如果 Saga 是该工作的正确工具,鉴于只能通过其唯一 ID(在我的情况下为 UUID)检索聚合,它如何识别属于用户的订单?

继续,假设每个聚合代表一个事务边界,如果系统崩溃 CustomerpostalAddress已更新(CustomerAddressUpdated 事件被持久化到事件存储)但 之前 OrderDeliveryAddressUpdated可以更新(即,在两个事务之间),然后系统处于不一致的状态。

问题 3. 如何检测并纠正此类“违反”一致性规则的行为?

最佳答案

在大多数情况下,订单的交货地址应该独立于任何其他数据更改,因为客户可能希望将订单发送到任意地址。话虽如此,我将就如何解决这个问题给出我的 2c:

Is the best place to handle this in a process manager?



是的。你应该有一个 OrderProcess .

How would one get hold of the correct OrderProcess instance given that it can only be retrieve by aggregate id?



没有什么可以阻止添加任何将数据关联到聚合 ID 的额外查找机制。在我的实验性的、即将上线的机制中,称为 shuttle-recall我有一个 IKeyStore将任意键关联到 AR Id 的机制。因此,您将能够关联类似 [order-process]:customerId=CID-123; 的内容。作为某些聚合的关键。

How are such "violations" of consistency rules detected and rectified?



在大多数情况下,如果可能,它们可以在带外处理。我是否应该从亚马逊订购东西,并在订单发货后尝试更改我的地址,订单仍将发送到原始地址。如果您将客户邮政地址链接到事件订单地址,您可以通知客户 n 个订单的地址已更新,但最近的订单(在一定范围内)没有更新。

至于在处理之前系统停机,您应该有一些有保证的交付机制来处理这个问题。我不会像对待消息传递基础结构(例如服务总线)中的系统事件那样对待这些领域事件。

只是一些想法:)

关于domain-driven-design - 在事件溯源中如何处理一致性违规?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34257897/

相关文章:

.net - 阅读有关DDD的内容后,您现在正在使用哪些做法?

architecture - CQRS:查询端的业务逻辑

design-patterns - GOF 中的命令模式 vs CQRS 含义

c# - 聚合根通过ID引用另一个聚合根,如何使用RavenDB保持完整性?

design-patterns - 您如何在领域驱动设计中使用具有工厂模式的接口(interface)?

cqrs - 如何从数据库“EventStore”中持久保存聚合/读取模型?

domain-driven-design - 领域驱动设计概念和与 CQRS 的关系

event-sourcing - 事件溯源 : multiple aggregates for event

java - EventSource 中的错误处理

api - 一起执行REST,CQRS和EventSourcing时如何在REST中支持Command?