Обработка ошибок агрегатора событий с откатом

Я изучал много общих способов, которыми разработчики проектируют / проектируют приложение на основе доменного дизайна (все еще пытаясь понять концепцию в целом). Некоторые из примеров, которые я видел, включали использование событий через агрегатор событий. Мне понравилась концепция, потому что она действительно разъединяет различные элементы / домены приложения.

У меня есть проблема: как откатить операцию в случае ошибки?

Например:

Скажем, у меня есть приложение для заказа, которое должно сохранить заказ в базе данных, а также сохранить копию заказа в формате PDF на CMS. Приложение запускает событие, что новый заказ был создан, и служба PDF, которая подписывается на это событие, сохраняет файл PDF. Между тем, при внесении изменений в базу данных выдается исключение. Проблема в том, что PDF был сохранен, но он не соответствует записи в базе данных.

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

Или... агрегатор событий не подходит для этого.

редактировать

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

Сначала я хотел ограничить зависимости, используя шаблон агрегатора событий.

2 ответа

Решение

Вы хотите, чтобы событие было зафиксировано в той же транзакции, что и операция в вашей базе данных.

В этом конкретном сценарии вы можете поместить событие в очередь, которая включается в вашу транзакцию, так что событие никогда не исчезнет, ​​если агрегат не будет сохранен. Это сделает создание PDF в конечном итоге согласованным; Если создание PDF не удается, вы можете решить проблему и автоматически повторить попытку.

Возможно, вы можете получить больше вдохновения в одном из моих предыдущих постов о возможных согласованных событиях в домене с RavenDB и IronMQ.

Обработка события до того, как оно действительно произошло (зафиксировано), работает, только если обработчик события участвует в транзакции. Сделайте обработчик событий транзакционным (например, сохраняя PDF в базе данных) или публикуйте и обрабатывайте события после совершения транзакции.

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