Введение
Методология Domain-Driven Design (DDD) активно применяется при разработке и эволюции сложных информационных систем с высокой нагрузкой. Одной из ключевых проблем в подобных архитектурах является обеспечение согласованности данных и управление конкурентным доступом.
Системы, основанные на DDD, как правило, строятся по многоуровневой архитектуре, включающей:
- Client Code – фреймворк, контроллеры внешнего API, представления;
- Application Layer – внутренний API для работы с доменом;
- Domain – вся бизнес-логика приложения, изолированная от остальных слоев;
- Infrastructure – вспомогательный код для обеспечения работы слоев выше: постоянное хранение данных, очереди, интеграционные события.
Такое разделение позволяет концентрировать бизнес-правила в доменной области и выносить технические детали за её пределы.
Управление конкурентным доступом
В высоконагруженных предметно-ориентированных системах необходимо учитывать риск параллельных изменений одних и тех же сущностей. Конфликты могут возникать в разных сценариях:
- одновременное изменение одного объекта несколькими пользователями или процессами;
- модификация объекта в момент, когда другие операции полагаются на его состояние;
- конкурентная обработка событий, влияющих на одно и то же агрегированное состояние.
Для минимизации подобных рисков применяется механизм блокировок (locks). Блокировка накладывается на сущность или группу связанных сущностей в момент выполнения критически важной операции. Таким образом предотвращается одновременное выполнение действий, способных нарушить согласованность данных.
Первым шагом является определение интерфейса для работы с блокировками на уровне домена:

Рис. 1
Реализация этого интерфейса располагается на уровне инфраструктуры. В одном из вариантов может использоваться механизм блокировок СУБД.

Рис. 2
Для целей модульного тестирования может использоваться Null-реализация:

Рис. 3
Далее создаётся сервис на уровне домена, определяющий правила блокировки сущностей:

Рис. 4
Здесь блокировка накладывается на сущность или её контейнер. Таймаут ожидания блокировки ограничен пятью секундами.
Следующим шагом является интеграция сервиса блокировок в прикладные команды. Для этого может использоваться декоратор команд:

Рис. 5
При необходимости декоратор можно использовать в других командах, добавив статический конструктор:

Рис. 6
Таким образом, каждая команда проверяет возможность получения блокировки. При неудаче выбрасывается исключение, при успехе выполняется операция, а затем блокировка освобождается.
Версионирование сущностей
Несмотря на эффективность блокировок, они не исключают полностью риск работы с устаревшими данными. Возможна ситуация, когда два процесса поочерёдно берут блокировку, но используют разные версии сущности. В результате изменения одного из них могут быть перезаписаны другим.
Для решения этой проблемы применяется контроль версий. Каждая сущность получает версионный атрибут:

Рис. 7
Версия назначается при маппинге из базы данных в доменную сущность. Пользовательский код прикладного уровня её изменить не может.
В репозитории выполняется проверка версии при сохранении:

Рис. 8
Если версия в базе данных не совпадает с версией, в сущности, выбрасывается исключение. При успешной записи версия увеличивается.
Выводы
В высоконагруженных предметно-ориентированных системах обеспечение согласованности данных требует сочетания нескольких подходов:
- использование механизма блокировок для предотвращения одновременного изменения одних и тех же сущностей;
- внедрение версионирования для защиты от перезаписи данных устаревшими состояниями;
- вынос технических аспектов синхронизации на инфраструктурный уровень с сохранением чистоты предметной модели.
Эти решения повышают надёжность систем и минимизируют риски коллизий при конкурентной работе множества пользователей или процессов. Их внедрение оправдано в условиях высокой нагрузки, где параллельный доступ представляет значительную угрозу для согласованности данных.
Таким образом, интеграция механизмов блокировок и версионирования в архитектуру, построенную на принципах DDD, является эффективным подходом к поддержанию согласованности данных в масштабируемых и сложных информационных системах.
.png&w=384&q=75)
.png&w=640&q=75)