Axonframework,有没有办法使用命令总线来锁定聚合

Axonframework, is there a way to lock aggregate using the command bus instead

我有两个具有相同标识符的聚合。我知道这听起来可能很奇怪,但我想这样做的原因是因为 BaseAggregate 有太多的功能,我想分离代码库,这样它仍然能够维护,也能够规模化。因此,FooAggregate 上的开发人员可以专注于自己的功能,同时共享 BarAggregate 上的开发人员可能需要的一些状态。这是同时向 FooAggregateBarAggregate 发送命令时的问题,它与 aggregateSequenceNumber 在活动商店。所以我做了很多研究,发现只要有命令被执行,聚合就会被锁定,但是这两个聚合部署在不同的 JVM 上,所以它不会阻止彼此执行命令。我希望它在命令总线上完成。所以假设 FooCommandBarCommand (具有相同的标识符)同时被调度。我希望命令总线等待 FooCommandBarCommand 成功,然后执行下一个命令。有没有一种方法可以将命令总线配置为这样的行为,它会影响性能吗?

abstract class BaseAggregate {
    @AggregateIdentifier
    public String identifier;
    // I use event-sourced approach so this state can be build up from events (with the same identifier)
    // and share among other services
    public List<String> sharedState;
}

class FooAggregate extends BaseAggregate {
    public void handle(FooCommand command) {
        // apply event
    }
}

class BarAggregate extends BaseAggregate {
    public void handle(BarCommand command) {
        // apply event
    }
}

在转到您的确切问题之前,让我重点关注以下内容:

So developers on FooAggregate can focus on their own features while shared some state that may need from the developers on BarAggregate.

您不应将状态从一个聚合实例读入另一个。聚合实例是独立的单元,它们在自己的 状态下执行验证。如果应扩大一致性边界以在您的系统中包含更多实体,则意味着您具有更大的聚合范围。

话虽如此,我猜您的问题措辞可能有点不对。我的依据是您正在使用 polymorphic aggregate,这是为您的域建模的好方法。从您的问题描述和代码中不清楚的是,您是否正确配置了它。

如果您正在使用 Spring,您可以将 Axon 的 @Aggregate 注释放在父 class 上。在你的例子中,就是 BaseAggregate。这将正确地告诉 Axon Framework 它正在处理多态聚合。

如果您不使用 Spring,则必须像这样使用 AggregateConfigurer

AggregateConfigurer<BaseAggregate> configurer =
AggregateConfigurer.defaultConfiguration(BaseAggregate.class)
                   .withSubtype(FooAggregate.class)
                   .withSubtype(BarAggregate.class);

话虽如此,我们可以继续讨论您实际要问的问题。 CommandBus是否可以为您锁定聚合

Axon Framework 的锁定方案适用于 Repository。 更具体地说,有一个 LockingRepository class 由 Axon Framework 中的 any Repository 实现。 该组件确保任何时候聚合被加载,它都会被锁定,确保不会发生重复访问。

但是,锁不是分布式锁,因为它本身会产生其他问题的整个方案。因此,为简单起见,这就是它所在的位置。

知道这一点,命令总线的任务不是锁定,而是命令总线确保同一聚合的命令一致路由。这实际上就是 Axon Frameworks 分布式命令总线所做的!

如果您使用 Axon 服务器,该行为将是无缝的。 请注意,这适用于 Axon Server 的标准版(免费)和企业版。如果愿意,您甚至可以选择 AxonIQ Cloud

如果您不使用 Axon 服务器,则必须自己设置分布式命令总线。这可以通过 Axon 的 Spring Cloud or JGroups 扩展来完成。