【发布时间】:2025-11-23 02:15:02
【问题描述】:
我们开始在我们的系统中发现一些场景,其中针对聚合的命令结果可能会影响其他相关聚合。
为了演示这个问题,考虑一个树结构,其中我们的节点有兄弟姐妹。每个节点都有一个排名,以确定它们在 UI 中的显示顺序,即
Node 1 | Ranking = 10
Node 2 | Ranking = 11
Node 3 | Ranking = 12
Node 4 | Ranking = 13
Node 5 | Ranking = 14
我们的节点聚合有一个不变量,它规定不能将排名设置为低于特定值(我们称之为 10)。如果将排名设置为低于此值,则会导致重新计算 所有 兄弟节点(包括相关节点)。为简单起见,假设计算只是根据上一个兄弟姐妹排名的两倍来计算排名
Node 1 | Ranking = 9 (cannot be accepted, reset to 50)
Node 2 | Ranking = 100
Node 3 | Ranking = 200
Node 4 | Ranking = 400
Node 5 | Ranking = 800
关键是,针对一个聚合的命令会导致更改到另一个聚合(或在这种情况下为多个)。
目前采取的方法是在到达域的途中拦截这些命令,“修复”它们并然后发送它们。所以在上面的示例场景中
- 我们收到来自客户的
ChangeNodeRankingCommand - 我们验证命令,即它是否在 10 以上的新排名
- 如果命令有效,则将其发送到域
- 如果命令无效,我们查询读取端提取所有受影响的聚合ID
- 我们使用调整后的排名为每个聚合(包括有问题的聚合)创建一个命令
- 我们将这些命令发送到域并丢弃原始命令
这很好用,但是有一些问题
- 我们一直在处理可能导致问题的陈旧数据(尝试更新随后被删除的实体等)
- 这些东西似乎是域逻辑,因此应该由域来处理
选择这样做的原因纯粹是从查询的角度来看,我们在我们的域中使用Event Sourcing,因此加载相关的聚合并不是微不足道的(考虑到我们事件存储的性质)。
这是一种合理的方法还是我在这里完全错过了一个技巧?
【问题讨论】:
标签: domain-driven-design distributed cqrs