CQRS/ES - обработка ошибок проекции

Я работаю над системой CQRS+ES, в основном использую инфраструктуру аксонов, но на самом деле этот вопрос относится к любой реализации. Итак, у меня есть обработчик команд и 1 или более обработчиков событий, работающих на разных JVM, контейнерах и т. Д., И в какой-то момент один из этих обработчиков сталкивается с ошибкой.

У нас есть два случая: "ожидаемая" бизнес-ошибка и "неожиданная" системная ошибка. Насколько я понимаю, мы сейчас находимся в асинхронном обработчике, и событие теперь является фактом, поэтому в действительности мы не можем напрямую откатить команду ни для одного случая (поскольку это может повлечь за собой откат ее в многочисленных других проекциях и прерывание CQRS).

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

В качестве примера, скажем, у нас есть команда, которая обновляет кредит клиента. Событие публикуется, одна проекция обновляет свою статистику "Всего кредитов", другая публикует обновление некоторого веб-сокета для пользовательского интерфейса и, наконец, еще одну, которая поддерживает состояние кредита - и этот последний обработчик завершается ошибкой. Должны ли мы отправить команду на откат бизнес-транзакции и снова вычесть кредит, снова обновить веб-сокет и т. Д.? И в случае аксона есть ли способ, которым это фиксируется как транзакция?

1 ответ

Решение

Я бы сказал, что принятие решения о том, что выполнение действия, то есть обработка команды - это нормально, всегда должно приниматься с помощью Командной модели / Агрегата. Агрегат, находящийся в неправильном состоянии для обработки действия, обычно приводит к "бизнес-исключению / ошибке".

Однако если вы принимаете решения при сбое обработки событий, вы добавляете некоторую логику принятия решений в службу обработки событий, которая в большинстве случаев, скорее всего, не имеет значения. Если такие службы обработки событий обновляют представления / модели запросов, но этого не происходит, я бы сказал, что это не является веской причиной для публикации "компенсирующей команды" в вашем агрегате для "отката / отмены события".

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

С точки зрения Axon Framework, вы можете обернуть CreditStateEventHandler в TrackingEventProcessor и вызвать сброс на этом обработчике событий, вызвав TrackingEventProcessor#resetTokens() функция. Это заняло позицию, что исключение, из-за которого ваш CreditStateEventHandler конечно, из-за неправильного кодирования, в противном случае воспроизведение приведет к точно такому же исключению.

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