从多个数据库填充聚合根

Populate aggregate root from multiple databases

我是 DDD 的初学者,想了解尝试从多个数据库填充单个聚合根是否是一种不好的做法?

我正在尝试设计一个系统,其中聚合根的所有属性都从一个数据库中填充,name 除外。 name 恰好在不同的数据库中,需要填充到聚合根中才能使用。

TIA

简短回答:是的,这是一种不好的做法(或者甚至不是一种做法)。

Martin Fowler表示:

A DDD aggregate is a cluster of domain objects that can be treated as a single unit

此声明的一个后果是聚合需要以事务方式存储。聚合代码将确保其在内存中的状态一致性,但如果您不能在数据库中强制执行这种一致性,就会出现问题。

将聚合存储在多个数据库中意味着您将无法以事务方式存储它们(您不应该这样做)或者您将使用分布式事务(您也不应该这样做)理想情况下)。

关于你的具体问题,要么是你的聚合有问题,要么是你的数据库设计有问题。

要查看您的聚合是否错误,请考虑为什么您需要该聚合中的 Name 属性?只有当它需要与聚合的其余部分进行事务性更改或聚合需要它来执行其业务逻辑时,它才应该存在。

如果聚合正确,则将 Name 属性 移动到与聚合其余部分相同的数据库(并且很可能相同 table)。如果出于某种原因您需要其他数据库中的 Name 以便可用于某些查询,请以最终一致性维护它(当 Name 在聚合中更改时,发布 en 事件并订阅它以更新查询数据库)。

I am a beginner in DDD and would like to understand if it is a bad practice to try to populate a single aggregate root from multiple database ?

是的。幸福的道路并不昂贵。

读取不一定是问题;如果您所做的只是生成一份报告,那么从多个来源提取数据就可以了(尽管我们当然认识到这些来源可能不会相互 "consistent"。

但是尝试使用两个数据库管理 writes,当事情开始出错时,很难确保数据的完整性 - 更新过程中的崩溃不会让您的数据保持健康状态。

好消息?如果数据已经分布在两个数据库中,则很可能有两个聚合要建模,而不是一个。采用 "customer" 等概念并在多个 聚合体 中共享它是完全正常的。

一旦你得到正确的聚合边界,你就可以以任何有意义的方式在你的数据库中安排聚合;模型中的每次修改都会为每个事务更新一个数据库,并保持业务不变性。

Mauro Servienti 的演讲 All Our Aggregates Are Wrong 可能是一个有用的起点。