Как справиться с проверкой согласованности на основе набора в CQRS? - PullRequest
28 голосов
/ 27 мая 2010

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

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

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

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

Ответы [ 4 ]

18 голосов
/ 23 июня 2010

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

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

4 голосов
/ 13 мая 2016

Три подхода описаны в Окончательная согласованность и проверка набора :

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

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

1 голос
/ 17 января 2015

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

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

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

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

0 голосов
/ 17 декабря 2016

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

...