在 Axon 中投影 @AggregateVersion

Projecting @AggregateVersion in Axon

我在聚合中使用注解 @AggregateVersion 来处理乐观并发。为了在请求中接收此版本,任何提出请求的人都需要首先从我的视图投影中获取当前版本。是否有一些标准方法来投影此版本字段(因为我猜,这不应该包含在事件 DTO 中)?

到目前为止,我唯一能想到的就是在投影中计算投影事件,并在每次投影一个事件时增加版本+1。

您可以将 MetaData 添加到消息(命令和事件)中。

https://docs.axoniq.io/reference-guide/configuring-infrastructure-components/messaging-concepts/supported-parameters-for-annotated-handlers 提供一些相关信息。

可以选择向元数据添加一些信息以防止乐观并发问题。

您可以发送如下消息:

MetaData metaData = MetaData.with("mykey", "myvalue");
metaData.put("lockVersion", currentVersion);
commandGateway.send(new GenericCommandMessage(doSomethingCommand, metaData));

在聚合命令处理程序中,您可以执行如下操作:

@CommandHandler
public handle(DoSomethingCommand cmd, MetaData metaData, @MetaDataValue("mykey") String someValue) {
    // ... version check between aggregateVersion and lockVersion

    MetaData eventMetaData = MetaData.with("lockVersion", aggregateVersion);
    AggregateLifecycle.apply(new GenericEventMessage(new SomethingDoneEvent(), eventMetaData));
}

和事件处理中的同类逻辑:

@EventSourcingHandler
public void on(SomethingDoneEvent evt, MetaData metaData) {
    // ...
}

免责声明:我是 Axon 框架和事件溯源的新手,所以这可能不是一个好的选择and/or有更好的方法可以做到这一点。

Jasper 的 MetaData 建议可以帮助您解决这个问题,但还有更简单的解决方案。

Axon 使用 ParameterResolvers 的概念(遗憾的是只有非常简短的描述 here, but in more depth here)来解决诸如 command/event/query、MetaDataMetaDataValue 之类的问题.但是,您也可以让框架解析事件源聚合 中的序列号是 聚合版本。您可以通过在事件处理函数中添加 @SequenceNumber 带注释的 Long 参数来实现。

因此,您可以像这样编写事件处理程序:

@EventHandler
public void on(YourEvent event, @SequenceNumber Long aggregateVersion) {
    // Update the query model And the aggregate version
}

话虽如此,这显然需要您在事件处理组件中处理聚合中的 all 事件,以便能够相应地更新版本。幸运的是,Axon 会识别您是否处理了事件负载的父 classes。因此,如果您定义事件 class 层次结构,确保来自给定聚合的所有事件实现 interface MyAggregateEvent。因此,您可以像这样编写一个事件处理程序来涵盖所有剩余的事件,仅用于聚合版本更新,否则您不会对此感兴趣:

@EventHandler
public void on(MyAggregateEvent event, @SequenceNumber Long aggregateVersion) {
    // Update the aggregate version only
}

希望对您有所帮助!


P.S。我刚刚注意到参考指南的 Handling Events page 确实说明了 @SequenceNumber 注释。