CQRS: хранение событий и их публикация - как мне сделать это безопасным способом?
Как я узнал в разделе Почему хранилище CQRS публикует события, а не хранилище событий? Задача репозитория CQRS - публиковать события. Все идет нормально.
Конечно, хранить события и публиковать их следует в рамках одной транзакции. Технически это означает запись одной (или нескольких) записей в хранилище и публикацию одного (или нескольких) событий на шину сообщений. Следовательно, простой транзакции базы данных недостаточно, она должна быть распределенной.
Сейчас, к сожалению, многие базы данных NoSQL (например, MongoDB) не поддерживают ACID-совместимые транзакции, даже не говоря о возможности иметь место в распределенной транзакции. Более того, существуют очереди сообщений, которые также не поддерживают распределенные транзакции.
Итак, вопрос: как мне с этим бороться?
Есть ли рекомендуемый шаблон для использования?
1 ответ
Ваш репозиторий может публиковать события, это не обязательно. Решением в этом случае является использование хранилища событий в качестве очереди. У вас будет фоновый процесс, который отслеживает новые события в хранилище событий, публикует их (например, на шине) и затем помечает их как отправленные.
Как всегда, есть компромиссы. Скорее всего, вам придется иметь дело с обменом сообщениями хотя бы один раз и идемпотентной обработкой. Это сложнее, чем использование простой распределенной транзакции.
Джонатан Оливер написал несколько постов на эту тему, которые могут вам помочь: Удаление 2PC, Как я избегаю двухэтапной фиксации, паттерны идемпотентности