DDD 一个聚合,两个可能的数据源

DDD One aggregate, two possible data sources

我有一个场景,我们决定在内部提取一些我们早就应该做的功能,因为它是我们核心领域的一部分。作为过渡的一部分,我们将暂时使用外部服务来存储和检索 Widgets 或我们的数据库,具体取决于类型。当与我们的本地数据库交互时,我们将使用乐观并发,这将向我们的 Widget 添加一个 version 字段,而在与外部服务交互时该字段不存在。

这里规范的领域驱动设计解决方案是什么?对此进行抽象的最佳方法是什么?应该在哪里实施?我的第一直觉是在应用程序服务层实现一个抽象工厂模式,但有人可能会争辩说这都可以抽象到存储库中。这样,当我们拉出外部服务时,消费者就不需要进行更改。由于我们正在使用聚合设计并且没有过于复杂的用例,因此我们不需要担心工作单元或类似的东西。交易问题完全在存储库中维护。

由于存储库负责存储抽象,我认为存储库也有责任与多个存储进行协调。

您可以实现类似于:

现在,如果您必须支持 expectedVersion,您可以在接口的合同中明确指出 expectedVersion 可能不会被所有实现支持,并且会抛出或根本不会被兑现。

"There would be a unique constraint on the entity ID + version number."

这适用于并发冲突,但无论如何都无法防止 non-concurrent 丢失更新,例如

  1. 客户端 C1 在屏幕上加载小部件 W(v1)。

  2. 客户端 C2 在屏幕上加载小部件 W(v1)。

  3. 客户端 C2 进行更改并保存(例如更新描述)。

  4. 存储库在内存中加载 W(v1) 并保存回 W(v2)。

  5. 客户端 C1 进行更改并保存(例如更新描述)。

  6. 存储库在内存中加载 W(v2) 并保存回 W(v3)。

最终C2的description更新无声无息的丢失了。您通常可以通过将预期版本与命令一起发送来解决此问题。