Как обрабатывать транзакцию в управляемой событиями архитектуре?

В настоящее время я играю с DDD & CQRS, и я перешел к устаревшему приложению.

Допустим, у меня есть объект Article, на который я могу голосовать.

Когда голосование публикуется в статье, я хочу увеличить или уменьшить счетчик, соответствующий стоимости голосования.

Этот счетчик является частью моей модели Query и, следовательно, я не думаю, что он подходит для модели домена. По этим причинам я решил написать CastArticleVoteService, в котором я помещал бизнес-логику о голосовании, и я отправляю событие для обработки с помощью специального обработчика событий, который по очереди обновляет счетчик в базе данных.

Прежде всего, я был настроен скептически, потому что сказал себе: «Эй, процесс обновления счетчика должен быть в той же транзакции, что и та, которая хранит данные». Но это, очевидно, неправильно, если у меня есть постоянство полиглота (то есть: MySQL / Redis).

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

Какие-нибудь советы?

Хорошо, вот мой вопрос по вашему вопросу:

В архитектуре, event driven и CRQS , также часто используется event sourcing в качестве шаблона.

Это означает, что ваши голоса не будут храниться в качестве счетчика ( state ), а скорее как голосование вверх / вниз ( fact ).

В своем сценарии, чтобы запросить, сколько голосов накопила статья, вы можете прочитать все события, связанные с агрегатом, и применить их по одному (в памяти) в том порядке, в котором они произошли, и получить окончательное состояние этого агрегатного экземпляра ( article ).

Иногда, когда объем событий велик, моментальный снимок сохраняется на самых последних фактах, возникающих в результате применения этих событий к совокупности.

Стоит отметить : будьте осторожны с побочными эффектами при применении событий, чтобы получить состояние. Поскольку, если событие «вверх / вниз» привело к тому, что статья закрылась, например, и отправила электронное письмо автору, то вы не хотите, чтобы это письмо отправлялось снова при повторном воспроизведении этих событий.

Подумайте об этом как о финансовом эквиваленте дебетовых / кредитных событий в банке. Банки не просто сохраняют ваш баланс. Они фактически хранят все ваши транзакции, а затем выполняют сверку и обновляют баланс.

Некоторые транзакции происходят немедленно, если счета должника / кредитора находятся в одном банке

Что это дает вам из коробки?

  • Масштабируемость ; это оптимизированная для записи архитектура, которая может обрабатывать более крупные запросы для более быстрого изменения состояния приложения без транзакций и блокировки
  • Прослеживаемость ; при проверке вашей системы вы не только узнаете, где находитесь (текущее состояние), но и узнаете, как / почему вы там (события)

Кроме того, поскольку у вас есть поток данных во всех пользовательских взаимодействиях с системой, вы можете впоследствии использовать эти данные по-разному для новых функций, о которых вы не могли бы подумать с самого начала проектирования системы (например, Google Analytics).

Дальнейшее чтение:

  • Шаблон поиска событий – Мартин Фаулер
  • Основы поиска событий – eventstore Db
  • Зачем использовать Event Sourcing – Грег Янг
  • MSDN: шаблон поиска событий
  • MSDN: использование событий в высокораспределенных архитектурах

Агрегаты определяют границы транзакций. Когда вы решаете, для архитектуры, управляемой событиями, вы решаете о возможной согласованности. Поэтому вам просто нужно выбрать: транзакцию ИЛИ событие.

Обратите внимание, что в большинстве случаев конечная консистенция полностью подходит для бизнеса. Это только разработчики, у которых есть транзакционный фетиш, имплантируемый лекциями РСУБД / «промывание мозгов» в университете;)