Как мне выполнить шаги компенсации / отката для Saga Orchestration с Axon Framework? - PullRequest
0 голосов
/ 29 мая 2020

Для случая использования, когда я хочу реализовать Saga Orchestration для пары сервисов с Axon, я построил:

  • order-service (оркестратор саги с Spring boot + Axon Framework )
  • платежный сервис (микросервис)
  • сервис доставки (микросервис)

Тогда у меня есть класс, аннотированный @ Saga с 3 шагами / обработчиками событий:

  • Заказ создан (первая услуга)
  • Оплата произведена (вторая услуга)
  • Заказ отправлен (третья услуга)
  • Заказ фактически создан

Мой вопрос: как я должен откатить / компенсировать все предыдущие выполненные шаги , если, например, служба доставки не работает ?

Из документации у меня есть некоторые сомнения по поводу:

  • нужно ли мне создавать новый класс с @Saga?
  • на сбой службы должен ли я генерировать исключение или отправлять ошибку другой команде / событию
  • как мне звоните SagaLifecycle.end()

Было бы здорово иметь решение, показывающее некоторый код. Спасибо!

1 Ответ

2 голосов
/ 02 июня 2020

Хорошо реализованная Saga может справиться с любыми ошибочными сценариями ios, возникающими из транзакции, которой управляет Saga. Таким образом, после любой операции , отправленной из саги, вы должны ожидать исключительного случая, на который вы отреагируете. Это эта реакция, которая является компенсирующим действием, которое вы ищете.

Теперь, go по вашим точным вопросам:

нужно ли мне создайте новый класс с помощью @Saga?

Вполне уверен, что вам не нужна новая сага для разрешения исключительных случаев в вашем домене. Так что нет.

в сервисе, который завершился неудачно, если я выберу исключение или отправлю ошибку другой команде / событию

Я бы go либо с исключением, либо с здесь событие, а не команда (поскольку (Axon) Saga не обрабатывает команды). Независимо от того, используете ли вы go любой из маршрутов, зависит от того, является ли событие важным бизнес-событием, поэтому его необходимо хранить в событии на неопределенный срок. Однако использование события будет означать, что вы разделяете отказоустойчивое поведение вашей саги между отдельными обработчиками событий саги, что я лично не предпочел бы. Таким образом, я предпочитаю генерировать исключение из одной из служб, которые будут обрабатываться сагой. Впоследствии, если вам нужно сохранить исключительное событие, просто опубликуйте sh событие рядом с ним.

как мне вызвать SagaLifecycle.end ()

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

Чтобы прояснить мои намерения, вот некоторый (псевдокод), показывающий, где Я бы выполнил компенсирующее действие:

private transient CommandGateway commandGateway;

@SagaEventHandler(assocationProperty = "some-association)
public void on(SomeEvent event) {
    // Validate/set state if necessary
    commandGateway.send(new SomeCommand(...))
                  .exceptionally(exception -> {
                      // Dispatch compensating action through service/CommandGateway
                  });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...