Проектирование @AggregateVersion в Axon - PullRequest
0 голосов
/ 22 января 2020

Я использую аннотацию @AggregateVersion в своем агрегате для обработки оптимистического c параллелизма. Чтобы получить эту версию в запросе, любой, кто делает запрос, должен сначала получить текущую версию из моей проекции. Есть ли какой-нибудь стандартный способ проецирования этого поля версии (поскольку, я думаю, это не должно быть включено в события DTO)?

Пока что единственное, что я могу придумать, - это просто подсчитать спроецированные события в проекции. и увеличивайте версию +1 каждый раз, когда я проецирую одно из событий.

Ответы [ 2 ]

3 голосов
/ 23 января 2020

Предложение MetaData Джаспера могло бы вас туда привести, но есть более простое решение этой проблемы.

Аксон использует понятие ParameterResolvers (к сожалению, только очень кратко описанное здесь , но более подробно здесь ) для разрешения таких вещей, как команда / событие / запрос, MetaData или MetaDataValue. Тем не менее, вы можете также разрешить платформе порядковый номер, который для агрегированного события равен агрегатной версии. Вы можете сделать это, добавив @SequenceNumber аннотированный Long параметр в функцию обработки событий.

Следовательно, вы можете написать обработчик событий следующим образом:

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

Сказав, что очевидно, для этого потребуется обработать все события из агрегата в компоненте обработки событий, чтобы иметь возможность соответствующим образом обновить версию. К счастью, Axon распознает, если вы обрабатываете родительские классы полезных данных события. Таким образом, если вы определяете иерархию классов событий, обеспечивающая реализацию всех событий из данного агрегата interface MyAggregateEvent. Таким образом, вы можете написать обработчик событий, подобный этому, чтобы охватить все оставшиеся события только для сводных обновлений версий, которые вас иначе не интересовали бы:

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

Надеюсь, это поможет!


PS Я только что заметил, что на странице Обработка событий справочного руководства указана аннотация @SequenceNumber.

0 голосов
/ 23 января 2020

Вы можете добавить MetaData к сообщениям (командам и событиям).

https://docs.axoniq.io/reference-guide/configuring-infrastructure-components/messaging-concepts/supported-parameters-for-annotated-handlers дать некоторую информацию об этом.

Это может быть опция добавить некоторую информацию в метаданные, чтобы предотвратить оптимистические проблемы c параллелизма.

Вы можете отправлять сообщения, такие как:

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));
}

И такой же лог c в обработке событий:

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

Отказ от ответственности: я новичок в Axon Framework и Event Sourcing, так что, возможно, это не очень хороший вариант и / или есть более эффективные способы сделать это.

...