Подтвердить что ты не робот

Как обрабатывать проверку согласованности на основе набора в CQRS?

У меня довольно простая модель домена, включающая список тэгов Facility. Учитывая, что я использую CQRS и шину событий для обработки событий, связанных с доменом, как вы можете обрабатывать проверку на множестве? Например, скажем, у меня есть следующее требование:

  • Facility должно иметь уникальное имя.

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

Например, FacilityCreatedEvent находится в очереди обработки событий базы данных запроса, ожидающей обработки и записи в базу данных. В домен, подлежащий обработке, отправляется новый CreateFacilityCommand. Службы домена запрашивают базу данных чтения, чтобы узнать, есть ли еще один Facility, уже зарегистрированный с этим именем, но возвращает false, поскольку CreateNewFacilityEvent еще не обработан и не записан в хранилище. Новый CreateFacilityCommand теперь преуспеет и выкинет еще один FacilityCreatedEvent, который взорвется, когда процессор событий попытается записать его в базу данных и обнаружит, что еще один Facility уже существует с этим именем.

4b9b3361

Ответ 1

Решение, с которым я пошел, заключалось в том, чтобы добавить корневой узел System, который мог бы поддерживать список текущих имен Facility. При создании нового Facility я использую агрегат System (только один System как глобальный объект/синглтон) как factory для него. Если имя данного объекта уже существует, оно выдает ошибку проверки.

Это сохраняет ограничения проверки в пределах домена и не полагается на последовательное хранилище запросов.

Ответ 2

В подменю Конечная согласованность и установка валидации:

  • Если проблема редка или не важна, обратитесь к ней административно, возможно, отправив уведомление администратору.
  • Отправка события DuplicateFacilityNameDetected, которое может начать автоматический процесс разрешения.
  • Поддерживать службу, которая знает об используемых именах объектов, возможно, прослушивая события домена и сохраняя постоянный список имен. Перед созданием любого нового средства сначала проверьте эту службу.

Также см. этот связанный вопрос: Проверка уникальности при использовании CQRS и источника событий

Ответ 3

В этом случае вы можете реализовать простую службу стиля CRUD, которая в основном делает вставку в таблице Sql с ограничением первичного ключа.

Вставка будет выполняться только один раз. Когда дубликаты команд с тем же значением, которые должны существовать только один раз, агрегируют, агрегат вызывает службу, служба не выполняет операцию Insert из-за нарушения ограничения основного ключа, выдает ошибку, весь процесс завершается с ошибкой и никаких событий генерируются, нет отчетов в стороне запроса, возможно, сообщение об ошибке в таблице для проверки на постоянную согласованность, где пользователь может запросить информацию о состоянии обработки команды. Чтобы проверить это, просто запросите снова и снова модель представления состояния команды с помощью командного указателя.

Очевидно, что когда команда содержит значение, которое не существует в таблице для проверки первичного ключа, операция выполняется успешно.

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

Ответ 4

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