【问题标题】:Composite unique constraint on business fields with Axon使用 Axon 对业务领域的复合唯一约束
【发布时间】:2019-10-08 19:26:17
【问题描述】:

我们在系统中利用 AxonIQ 框架。我们在实现基于聚合业务字段的复合 uniq 约束时遇到了问题。

考虑以下聚合:

@Aggregate
public class PersonnelCardAggregate {

    @AggregateIdentifier
    private UUID personnelCardId;

    private String personnelNumber;

    private Boolean archived;

}

我们希望避免在未归档(归档 == 假)记录范围内出现人员编号重复。同时存档记录范围内可能存在人员编号重复。

查询端检查似乎不是一种选择。考虑到我们系统的最终一致性特性,可能同时存在多个相同personalNumber的创建请求,查询端可能落后。

解决办法是什么?

【问题讨论】:

    标签: cqrs axon eventual-consistency


    【解决方案1】:

    您要问的是,一旦您开始按照 CQRS 范式和 DDD 建模技术实施应用程序,就会出现一个问题。

    您的场景中的PersonnelCardAggregate 维护了单个“人事卡”的一致性边界。但是,您希望扩展此范围以实现系统中所有人员卡之间的唯一性约束。

    我觉得这个博客很好地解释了你遇到的“Set Based Consistency Validation”的问题。 我不会重复他的整个博客,但他总结为有四种解决问题的方法:

    1. 为您的人事卡引入锁定、事务和数据库约束
    2. 在发出命令之前使用混合锁定字段
    3. 真正依赖于最终一致的查询模型
    4. 重新检查域模型

    公平地说,如果您使用事件驱动的方法来更新命令和查询模型,选项 1 将不会起作用。 您在原始问题中已将选项 3 推回。

    鉴于我不是领域专家,我无法为您推断选项 4,但我猜测 PersonnelCardAggregate 不属于更大的封装聚合根。也许您所说的业务约束,因此可以删除或调整重用personalNumbers 的选项?就像我说的那样,我不能说这是对你的真实答案,因为我不是领域专家。

    剩下的选项 2 在我看来也是最实用的方法。 我觉得这需要在您的命令调度端结合缓存来处理快速连续的命令,以解决最终的一致性问题。为了捕捉更新仍然意外发生的情况,我将介绍某种形式的事件处理程序,它(1)从personalNumber/archived 的角度了解整套“PersonnelCards”,并且(2)可以通过调度补偿动作对错误的介绍做出反应。

    因此,您需要在应用程序的事件处理端引入一些业务逻辑,我强烈建议您将其与更新查询模型的应用程序部分分开(因为用例完全不同)。

    尽管如此,这是一个困难的话题,有多种方法可以解决它。 顺便说一句,这不是 Axon 特定的问题,而是通过 DDD 和 CQRS 对您的应用程序进行建模。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-21
      • 2016-06-19
      • 2018-08-01
      相关资源
      最近更新 更多