【发布时间】:2020-05-06 22:32:41
【问题描述】:
我是 DDD 的初学者,想了解尝试从多个数据库填充单个聚合根是否是一种不好的做法?
我正在尝试设计一个系统,其中聚合根的所有属性都从一个数据库中填充,name 除外。 name 恰好位于不同的数据库中,需要填充到聚合根中才能使用。
TIA
【问题讨论】:
标签: domain-driven-design aggregateroot
我是 DDD 的初学者,想了解尝试从多个数据库填充单个聚合根是否是一种不好的做法?
我正在尝试设计一个系统,其中聚合根的所有属性都从一个数据库中填充,name 除外。 name 恰好位于不同的数据库中,需要填充到聚合根中才能使用。
TIA
【问题讨论】:
标签: domain-driven-design aggregateroot
我是 DDD 的初学者,想了解尝试从多个数据库填充单个聚合根是否是一种不好的做法?
是的。幸福的道路并不昂贵。
读取不一定是问题;如果您所做的只是生成一份报告,那么从多个来源提取数据就可以了(尽管我们当然认识到这些来源可能彼此“不一致”。
但是尝试使用两个数据库管理写入,当事情开始出错时,很难确保数据的完整性 - 更新过程中的崩溃不会将您的数据留在健康的状态。
好消息?如果数据已经分布在两个数据库中,那么您很可能有两个要建模的聚合,而不是一个。采用“客户”之类的概念并在多个聚合 之间共享它是完全正常的。
确定聚合边界后,您可以以任何有意义的方式在数据库中安排聚合;模型中的每次修改都会为每个事务更新一个数据库,并保持业务不变量。
Mauro Servienti 的演讲 All Our Aggregates Are Wrong 可能是一个有用的起点。
【讨论】:
简短回答:是的,这是一种不好的做法(甚至不是一种做法)。
如Martin Fowler所表达:
DDD 聚合是可以视为单个单元的域对象集群
此语句的结果之一是聚合需要以事务方式存储。聚合代码将确保其在内存中的状态一致性,但如果您无法在数据库中强制执行该一致性,您将遇到问题。
将聚合存储在多个数据库中意味着您要么无法以事务方式存储它们(您不应该这样做),要么您将使用分布式事务(理想情况下您不应该这样做) .
关于您的具体问题,您的聚合错误或数据库设计错误。
要查看您的聚合是否错误,请考虑为什么您需要该聚合中的 Name 属性?只有当它需要与聚合的其余部分进行事务更改或聚合需要它来执行其业务逻辑时,它才应该存在。
如果聚合正确,则将Name 属性移动到与聚合的其余部分相同的数据库(并且很可能是同一个表)。如果出于某种原因您需要在该其他数据库中使用 Name 以便对某些查询可用,请保持最终一致性(当聚合中的名称更改时,发布事件并订阅它以更新查询数据库) .
【讨论】: