Domain driven design 处理聚合之间的最终一致性失败

Domain driven design 处理聚合之间的最终一致性失败,domain-driven-design,eventual-consistency,domain-events,Domain Driven Design,Eventual Consistency,Domain Events,我是DDD的初学者,遇到了一种情况,即在同一事务中不修改超过1个聚合,使用域事件解决其他聚合中的更改。(见有效聚合项目) 情况如下:用户计划将患者转移到另一家医院。当传输时间到来时,用户在列表中选择它并单击“开始”。但是,此操作改变了三个聚合: 传输:标记为已启动。例如:transfer.Start() 患者:标记为正在转移。例:patient.MarkAsInTransfer() 医院:你必须为即将到来的病人预留一个地方。例:医院;。保留地点(病人) 因此,当传输开始时,它会引发一个事件Tra

我是DDD的初学者,遇到了一种情况,即在同一事务中不修改超过1个聚合,使用域事件解决其他聚合中的更改。(见有效聚合项目)

情况如下:用户计划将患者转移到另一家医院。当传输时间到来时,用户在列表中选择它并单击“开始”。但是,此操作改变了三个聚合:

传输:标记为已启动。例如:transfer.Start()

患者:标记为正在转移。例:patient.MarkAsInTransfer()

医院:你必须为即将到来的病人预留一个地方。例:医院;。保留地点(病人)

因此,当传输开始时,它会引发一个事件TransferStarted

但是,由于某些原因,当转移已经发生时,在处理TransferStarted事件(更改患者状态或在目的地医院预订位置)时会发生错误

既然患者已经在转院,如何处理这种情况?我需要忘记并使用事务一致性,在同一事务中修改三个聚合?使用域服务来完成它

请记住,我遵循的是聚合事务规则

既然患者已经在转院,如何处理这种情况?我需要忘记并使用事务一致性,在同一事务中修改三个聚合?使用域服务来完成它

这里发生的事情有几个方面

1) 根据你的描述,你是在与现实世界中的实体打交道;真实世界的记录簿是真实世界,而不是您的域模型。因此,当您收到来自真实世界的“域事件”时,您需要适当地处理它

2) 协作领域由现实世界中的多个资源提供贡献,本质上是“最终一致的”。这里的人不知道那里发生了什么,反之亦然——他们只能根据当地掌握的信息采取行动,如实报告他们正在做的事情

这意味着,在实践中,您需要将您的“聚合”视为对现实世界中发生的事情进行簿记,并记录与政策冲突的行为(有时称为“异常报告”)

3) 通常在协作过程中,“聚合”是过程本身的实例,而不是参与过程的实体

既然患者已经在转院,如何处理这种情况

您可以调用域专家提供给您的应急协议

一种思考的方式是想象一堆短信四处传播。你从主治医生那里收到一条消息,宣布转院开始,过了一会儿你从目的地医院收到一条消息,它处于封锁状态

现在怎么办

嗯,我不确定-这不是我的领域。但这可能类似于向主治医生发送消息,宣布目的地已经关闭

这里需要注意的重要事项是:(a)在不同地方发生的冲突是分布式协作系统的一个特性,您必须对此进行规划——竞赛条件是真实的;(b)您在其他任何地方所掌握的关于事态的信息总是陈旧的,并且可能会被修改


仔细阅读。现实世界就在外面,你所有关于它的信息都是陈旧的。另外,回顾一下。

当我面对这类问题时,我问自己的第一件事是:“我的汇总是否正确,他们是否有正确的责任?”?毕竟,聚合是一个事务边界,它封装了给定流程的数据和业务逻辑。如果一个流程需要3个聚合,那么实际上它们是否可能是单个聚合

在您的特殊情况下,转院对我来说听起来像是一个集合(例如,必须执行一些业务规则和一些与之相关的数据),但医院和患者对我来说是可疑的。他们封装并负责什么样的数据和业务逻辑?这显然取决于这些聚合所处的有界上下文,但我会仔细检查。我想他们都在同一个BC

例如,我会考虑:为什么患者需要标记为转移中?它执行什么样的业务规则?如果原因是为了避免患者被转移不止一次,那么不应该是从转移中听到事件(转移从何而来?),而应该是创建转移的事件(参见Udi Dahan的)。因此,如果要转移患者,请执行Patient.TransferTo(otherHospital),它将检查是否满足启动转移的条件,如果满足,则发送创建转移的命令。然后,患者可以收听TransferStarted、TransferCancelled和TransferCompleted事件,以安全地更新自己的状态(因为新的传输在前一个传输成功或不成功完成之前不会启动)

从这一点上讲,医院房间的分配将是转院和医院之间的事情,患者不需要知道任何相关信息

但是关于医院,我现在还不知道,因为在我看来,一个集合管理整个医院的房间分配是不对的。似乎有很多数据和责任,而且,我也不清楚是否需要事务性:为什么100号房间的患者a分配必须是事务性的,而210号房间的患者B分配必须是事务性的?如果你想象一个完整的医院,那就是在一个集合中有很多房间和病人,还有很多意外事件,这不允许同时发生变化。奥布维