CQRS - когда объединяются корни в базе данных и в файле?
Я начал планировать свой первый проект CQRS с источником событий, и из-за нехватки времени часть модели останется в файлах XML. Что я понимаю из DDD, так это то, что каждое обновление выполняется для корня агрегата, и если я хочу изменить другой корень агрегата из первого (событие инициируется в домене), то сначала выполняется команда для изменения второго агрегата. Каждое изменение имеет собственную транзакционную границу.
Теперь, что меня беспокоит, если я зафиксировал изменение в первом агрегате (в базе данных), как мне справиться с ситуацией, когда второй агрегат (запись в файл в этом случае) не выполняется?
Я мог бы выполнить команду, чтобы сначала обновить файл первым (второй агрегат), а затем выполнить команду, чтобы изменить первый агрегат, но еще раз у меня может произойти сбой второй команды, но в этом случае у нас есть две отдельные команды, которые, кажется, идут вразрез идея событий, возникающих в домене, которые обрабатываются как в первом случае.
Я полагаю, что даже если я не использовал файл и все изменения были записаны в базе данных, существует вероятность, что второе совокупное изменение может потерпеть неудачу. Правильно ли я так думаю?
Все еще пытаюсь понять концепции в моей голове, поэтому любая помощь будет оценена.
2 ответа
Второй агрегат может генерировать что-то вроде события UpdateFailed. Это, в свою очередь, может быть выполнено путем отправки команды отката в первый агрегат.
У вас есть конкретный пример? Часто потребность в транзакции, которая пересекает совокупные границы, может быть решена путем уточнения модели.
Обновление: также взгляните на концепцию под названием "Сага". Сага может быть полезным координатором таких процессов, как ваш. Сага - это обработчик событий, который отправляет команды в соответствии с полученными событиями. Сага может быть просто координатором без сохранения состояния, но она также может быть с состоянием, поэтому она знает, какие команды должны быть компенсированы в случае неудачи последующей. Просто гуглите "CQRS Saga" и отправляйтесь оттуда. Особенно полезны статьи Грега Янга и Рината Абдуллина.
Я думаю, у вас есть вопрос здесь больше о согласованности транзакций, чем о чем-либо еще. Поскольку вы не указали для разговора реального делового контекста, трудно полностью прокомментировать подходящее решение.
Однако в целом, если второй агрегат должен обновляться на основе команды до первого агрегата, то, возможно, они находятся в одной транзакции (DDD "Bounded-Context"). Это действительно трудно понять без контекста.
В противном случае, обычно, если второй агрегат подписан на событие первого, это сообщение принимается в транзакции (на этот раз принадлежащей второму агрегату), и если эта операция не может быть выполнена, обработка события откатывается и повторно попробовал (или отправил в другое место для ручного действия (как очередь ошибок)).
Это помогает?