Таблица записей саг / Коллекция саг остается пустой

Я слежу за Пример AxonBank, чтобы понять реализацию Saga во фреймворке Axon и иметь такой код для начала и завершения саги.

@Saga
public class MoneyTransferSaga {
    @Inject
    private transient CommandGateway commandGateway;

    private String targetAccount;
    private String transferId;

    @StartSaga
    @SagaEventHandler(associationProperty = "transferId")
    public void on(MoneyTransferRequestedEvent event) {
        System.out.println("Inside start saga for money transfer event");
        targetAccount = event.getTargetAccount();
        transferId = event.getTransferId();
        SagaLifecycle.associateWith("transactionId", transferId);
        System.out.println("## These are the params going into WMC : sourceAccount: " + event.getSourceAccount()
                + " transferID: " + transferId + " event.getAmount: " + event.getAmount());
        commandGateway.send(new WithdrawMoneyCommand(event.getSourceAccount(), transferId, event.getAmount()),
                new CommandCallback<WithdrawMoneyCommand, Object>() {
                    @Override
                    public void onSuccess(CommandMessage<? extends WithdrawMoneyCommand> commandMessage,
                            Object result) {

                    }

                    @Override
                    public void onFailure(CommandMessage<? extends WithdrawMoneyCommand> commandMessage,
                            Throwable cause) {
                        System.out.println("On failure of withdraw money command inside saga ");
                        System.out.println("###################### Cause of failure = " + cause);
                        commandGateway.send(new CancelMoneyTransferCommand(event.getTransferId()));
                    }
                });
    }

    @SagaEventHandler(associationProperty = "transactionId")
    public void on(MoneyWithdrawnEvent event) {
        System.out.println("Inside saga event handler for monney withdrawnevent");
        commandGateway.send(new DepositMoneyCommand(targetAccount, event.getTransactionId(), event.getAmount()),
                LoggingCallback.INSTANCE);
    }

    @SagaEventHandler(associationProperty = "transactionId")
    public void on(MoneyDepositedEvent event) {
        System.out.println("Inside saga event handler for money deposited event");
        commandGateway.send(new CompleteMoneyTransferCommand(transferId), LoggingCallback.INSTANCE);
    }

    @EndSaga
    @SagaEventHandler(associationProperty = "transferId")
    public void on(MoneyTransferCompletedEvent event) {
        System.out.println("Inside Endsaga for money transfer complete event");
    }

    @SagaEventHandler(associationProperty = "transferId")
    public void on(MoneyTransferCancelledEvent event) {
        end();
    }
}

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

Все записи также существуют в domain_event_entry, но таблицы saga_entry и association_value_entry остаются пустыми независимо от того, успешна ли транзакция или нет.

Сначала я подумал, что это может быть из-за неправильно настроенного хранилища саг, поэтому я настроил хранилище саг с MongoSagaStore, но все же коллекция саги остается пустой.

Так что мне здесь чего-то не хватает, или аксон просто удаляет данные из этих таблиц после завершения саги?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
626
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

AxonFramework автоматически удалит запись саги из своего хранилища, включая любые ассоциации, когда она закончится. Таким образом, вы всегда будете видеть информацию только об активных экземплярах.

В примере приложения все компоненты шины используют реализацию «Simple ...», что в основном означает, что все действия выполняются в одном потоке. Следовательно, как только вы получите OK или NotOK, все действия Saga также будут прекращены. Если бы вы заменили их реализациями Async или Distributed, это уже не так. Вам вернут ОК до завершения всего процесса.

есть ли способ изменить это поведение или Axon делает это специально?

TGW 02.08.2018 15:04

Он делает это специально, потому что «сложная бизнес-операция», которую обозначает сага, округляется в большую сторону. То, что сделано, не обязательно должно задерживаться. Кроме того, репозиторий Saga не служит для выполнения запросов, он просто служит способом сохранить «сложную бизнес-транзакцию», которую можно будет забрать позже. Тем не менее, самый простой способ не удалять сагу - это не вызывать функцию SagaLifecycle.end() и не добавлять аннотацию @EndSaga к каким-либо обработчикам событий.

Steven 03.08.2018 10:06

Моей первой мыслью было не завершение саги. Я подумал, есть ли какая-то конфигурация вместо этого, но ваше объяснение имеет большой смысл, поэтому технически единственный след существования саги после ее окончания находится в domain_event_entry.

TGW 29.08.2018 10:59

@Allard, я понимаю поведение хранилища Saga в примере AxonBank. Однако в примере AxonTrader (github.com/AxonFramework/Axon-trader) саги о продаже / покупке не завершаются в одном потоке, они могут охватывать несколько взаимодействий с пользователем. Однако я до сих пор не вижу постоянства саги в таблице SAGAENTRY. Это все сделано в памяти? Что будет, если произойдет перезагрузка сервера? (Я понимаю, что в этом примере используется hsql в памяти, я говорю, что если это делается в реальной базе данных, поведение сохраняемости должно быть таким же). Любой пример, демонстрирующий настойчивость саги, будет очень полезен.

Baimai Wu 17.01.2019 14:37

Другие вопросы по теме