我们的开发团队目前正在探索有效的模式来处理并发更新可能导致数据不一致的情况。我们遵循领域驱动设计 (DDD) 原则,在我们的代码库中纳入不变量检查。
为了说明这一挑战,请考虑以下示例:
示例1:唯一用户名要求:
问题: 两个用户同时尝试使用同一用户名注册。 结果: 验证用户名唯一性的两个查询都返回 true,导致添加两个具有相同用户名的用户。
示例2:批量作业执行:
问题: 两个用户同时启动一个批处理作业,违反了只允许一个作业执行实例的约束。 结果: 两个作业执行同时启动,与预期的单次执行相反。
例3:购物篮预算限额:
问题: 用户利用竞争条件同时添加两个项目,从而超出了预算限制。 后果: 两项添加都被允许,超出了预算限制。
经过研究,我们确定了解决这些问题的几种潜在模式:
1。数据库唯一约束:
优点:解决了示例 1。 缺点:可能不是示例 2 和 3 的全面解决方案。
2。聚合的 DDD 技术:
优点:引入新的事务边界。 缺点: 不是示例 1 的直接解决方案;示例 2 和 3 的有效性有所不同。
3.集群感知命令处理程序:
优点:按顺序处理命令,有可能解决所有三种情况。 缺点:增加了系统的复杂性。
4。锁表:
优点:可以解决示例2。 缺点:增加复杂性;可能无法解决所有场景。
5。数据库锁(悲观锁):
优点: 可以作为示例 2 的解决方案。 缺点:实施复杂性。
6。不采取行动(权衡决策):
优点:权衡实施成本与并发问题的可能性和影响。 缺点:接受一定程度的风险。
7。变体 6 的补充:重复数据检测的质量报告:
优点:提供监控方法。 缺点:反应性而非预防性。
我们对社区的疑问:
其他模式:是否有其他模式可以解决并发更新挑战?
模式目录:是否有著名的模式目录可以解释这些模式及其优缺点?
代码示例:是否有专门为 Java、JPA 和/或 Spring Data 定制的这些模式的代码示例?
我们感谢您在应对这一挑战方面的见解和帮助。
谢谢!
提出的每个问题都是独特的,每个问题都需要自己的解决方案。以下是我的建议:
示例1: 我会在数据库中使用唯一约束。我想这或多或少是我听过的 DDD 专家讨论这个问题的共识。
示例2: 我可能有一个关于工作的传奇。每种类型的工作都会有一个类似的例子。当用户想要启动作业时,他发送一个命令来启动作业,适当的 saga 实例通过将其状态更新为“已启动”并发布实际启动工作的事件来处理它。传奇上的乐观并发以及发件箱模式将防止作业启动两次。
示例3 将商品添加到购物车将通过购物车的聚合根。在购物车上使用乐观并发。