Составное уникальное ограничение для бизнес-полей с помощью Axon - PullRequest
1 голос
/ 08 октября 2019

Мы используем AxonIQ Framework в нашей системе. Мы столкнулись с проблемой реализации составного uniq-ограничения, основанного на агрегированных бизнес-полях.

Рассмотрим следующее Aggregate:

@Aggregate
public class PersonnelCardAggregate {

    @AggregateIdentifier
    private UUID personnelCardId;

    private String personnelNumber;

    private Boolean archived;

}

Мы хотим избежать дубликатов personalNumber в области НЕ-архивированных (архивированных== ложные) записи. В то же время дубликаты персонала и числа могут существовать в области архивных записей.

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

Каким будет решение?

Ответы [ 2 ]

0 голосов
/ 05 ноября 2019

https://foreverframe.net/how-to-guarantee-username-uniqueness-with-cqrses/

Описывает несколько подходов. В решении 4, если вы сохраняете свои материализованные прогнозы в базе данных, вы можете обнаружить дубликат и затем откатить команду создания. Это позволяет исключить любые гонки данных, при этом используя базу данных на стороне запроса.

0 голосов
/ 09 октября 2019

То, что вы спрашиваете, - это проблема, которая может возникнуть, как только вы начнете реализовывать приложение в соответствии с парадигмой CQRS и методами моделирования DDD.

PersonnelCardAggregate в вашем сценарии поддерживает границу согласованностисингл "Кадровая карточка". Однако вы хотите расширить эту область, чтобы достичь ограничений уникальности среди всех кадровых карт в вашей системе.

Мне кажется, что этот блог объясняет проблему " проверки согласованности на основе набора ", которой вы являетесьвстречая довольно приятно. Я не буду повторять весь его блог, но он резюмирует, что у него есть четыре варианта решения проблемы:

  1. Введение блокировок, транзакций и ограничений базы данных для вашей карты персонала
  2. Использованиеполе гибридной блокировки перед выполнением команды
  3. Действительно в конечном итоге непротиворечивая модель запроса
  4. Пересмотреть модель домена

Если честно, вариант 1 не будетесли вы используете управляемый событиями подход к обновлению вашей модели команд и запросов. Вариант 3 был отклонен вами в исходном вопросе.

Вариант 4 - это то, что я не могу для вас сделать вывод, учитывая, что я не эксперт в области, но я предполагаю, что PersonnelCardAggregate не принадлежитбольший инкапсулирующий агрегатный корень. Может быть, указанное вами ограничение бизнеса, таким образом, возможность повторного использования personalNumbers, может быть удалено или скорректировано? Как я уже сказал, я не могу утверждать, что это фактический ответ для вас, так как я не эксперт по предметной области.

Это оставляет вариант 2, который, на мой взгляд, также будет самым прагматичным. Я чувствую, что это потребовало бы комбинации кэша на вашей стороне диспетчера команд, чтобы иметь дело с быстрой последовательностью команд для решения возможной проблемы согласованности. Чтобы зафиксировать случаи, когда обновление по-прежнему происходит случайно, я бы представил некоторую форму обработчика событий, которая (1) знает весь набор «PersonnelCards» с точки зрения personalNumber / archived и (2) можетреагировать на ошибочное введение, отправляя компенсирующее действие.

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

В заключение, это сложная тема с несколькими путями ее решения. Кстати, это не столько проблема, специфичная для Axon, сколько моделирование вашего приложения с помощью DDD и CQRS.

...