cqrs - 使用 Axon 对业务领域的复合唯一约束
问题描述
我们在系统中利用 AxonIQ 框架。我们在实现基于聚合业务字段的复合 uniq 约束时遇到了问题。
考虑以下聚合:
@Aggregate
public class PersonnelCardAggregate {
@AggregateIdentifier
private UUID personnelCardId;
private String personnelNumber;
private Boolean archived;
}
我们希望避免在未归档(归档 == 假)记录的范围内出现人员编号重复。同时存档记录范围内可能存在人员编号重复。
查询端检查似乎不是一种选择。考虑到我们系统的最终一致性特性,可能同时存在多个具有相同personalNumber的创建请求,查询端可能落后。
解决方案是什么?
解决方案
您要问的是,一旦您开始按照 CQRS 范式和 DDD 建模技术实现应用程序,就会出现一个问题。
在PersonnelCardAggregate
您的场景中,维护单个“人事卡”的一致性边界。但是,您希望扩展此范围以在系统中的所有人员卡中实现唯一性约束。
我觉得这个博客很好地解释了你遇到的“基于集合的一致性验证”的问题。我不会重复他的整个博客,但他总结为有四个选项来解决问题:
- 为您的人事卡引入锁定、事务和数据库约束
- 在发出命令之前使用混合锁定字段
- 真正在最终一致的查询模型上
- 重新审视领域模型
公平地说,如果您使用事件驱动方法来更新您的命令和查询模型,选项 1 将不起作用。您在原始问题中已将选项 3 推回。
鉴于我不是领域专家,我无法为您推断选项 4,但我猜测它PersonnelCardAggregate
不属于更大的封装聚合根。也许您所说的业务约束,因此personalNumbers
可以删除或调整重用选项?就像我说的那样,我不能说这是对你的事实答案,因为我不是领域专家。
剩下的选项 2,在我看来也是最务实的方法。我觉得这需要在您的命令调度端组合缓存来处理快速连续的命令,以解决最终的一致性问题。为了捕捉更新仍然意外发生的情况,我将介绍某种形式的事件处理程序,它 (1) 从personalNumber
/archived
的角度了解整套“PersonnelCards”,并且 (2) 可以对错误的介绍做出反应发送补偿动作。
因此,您将在应用程序的事件处理端引入一些业务逻辑,我强烈建议将其与更新查询模型的应用程序部分分开(因为用例完全不同)。
总而言之,这是一个困难的话题,有几种方法可以解决它。顺便说一下,这不是 Axon 特定的问题,而是更多通过 DDD 和 CQRS 对应用程序建模的情况。
推荐阅读
- algorithm - 求解运行时间 Big Theta 表示法
- jquery - 日期选择器无法正确加载
- javascript - 使用 React.js 中的钩子从输入值编辑对象数据
- python - Python 程序在 1 次运行后中断
- python - 如何在保持在另一列范围内的同时锻炼列中两个值之间的差异?
- r - R:在图表之间切换
- mysql - Airflow 2.0.0:超过 MySQL 锁定等待超时
- c# - 更改公开的 COM 互操作方法名称 C#
- php - 如何检查日期是否在PHP中的日期数组中
- javascript - Firebase/Angular:从 Firebase 存储读取 JSON 文件