От команды к событию
Успешная команда может породить события. Сохраняйте их, только если версия потока соответствует версии, на которой было принято решение.
Путь записи
Примите команду, загрузите агрегат, вызовите его поведение и добавьте полученные события с ожидаемой версией.
Не фиксируйте успешную внешнюю операцию до её завершения. Например, запрос платежа и запись подтверждения авторизации — разные этапы.
Оптимистический контроль конкуренции
Если другая запись изменила версию потока, добавление событий будет отклонено. Загрузите агрегат заново и повторно оцените команду либо сообщите о конфликте.
Проверка версии обнаруживает конфликт записи. Инварианты предметной области определяют, допустима ли команда в новом состоянии.
Идемпотентность
Истечение времени ожидания не сообщает клиенту, была ли запись завершена. Повторяйте тот же запрос с тем же ключом идемпотентности и содержимым согласно контракту API.
Идемпотентность записи не равнозначна идемпотентности команды. Обработчик должен также учитывать повторные запросы на бизнес-операцию и побочные эффекты во внешних системах.
Типичные ошибки
Не принимайте решение по отстающей модели чтения, если оно требует актуального состояния агрегата. Не отказывайтесь от ожидаемой версии только ради отсутствия конфликтов.
Не запускайте обработку команд заново при воспроизведении событий. Восстановление записанного состояния и принятие решения по новой команде — разные операции.
Практическое упражнение
Обработайте две команды на одной загруженной версии. Убедитесь, что из конфликтующих записей успешна только одна, затем загрузите агрегат заново и определите результат второй команды.
Путь обучения Event Sourcing · Назад · Далее · Документация Chronacta
