Обновите два агрегированных экземпляра в одной транзакции

#domain-driven-design

Вопрос:

Допустим, у нас есть совокупный счет для банковской услуги. Кто-то хочет перевести деньги со своего счета на счет другого человека. Существует ряд правил: у плательщика должно быть достаточно денег на счете, а Счет получателя платежа должен быть активным. Если эти правила пройдут, то баланс на обоих счетах будет обновлен. В традиционной системе это можно легко сделать с помощью одной транзакции acid db.

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

Ответ №1:

В DDD это было бы недопустимо

На самом деле это не совсем так — здесь многое происходит.

Эванс (2003), а также Вон 2013 написали, что управление транзакциями-это не проблема модели домена, а скорее то, что управление транзакциями относится к коду приложения.

Однако существует реальная проблема с одновременным изменением нескольких агрегатов: для этого предполагается, что вы можете получить блокировки для этих объектов одновременно, а также зафиксировать все эти изменения вместе.

Это относительно просто, когда все изменяемые агрегаты хранятся в одной реляционной базе данных; но это становится очень сложным, когда агрегаты хранятся в разных местах.

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

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


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

Это или изменение способа моделирования ваших агрегатов. Иногда и то, и другое.

Например, довольно часто встречаются агрегаты, которые обрабатывают (короткоживущие) процессы, которые отличаются от долгоживущих агрегатов.

Когда я смотрю выписку по своей кредитной карте, плата обычно падает в одном из трех состояний: она еще не внесена в мою выписку (не видна), или она находится на рассмотрении (видна), или она фактически учтена как плата (видна). Очевидно, что что-то происходит «где-то еще», и эта информация в конечном итоге копируется в мое заявление, где я могу ее видеть.


Я вижу, как это можно сделать, но это добавляет много сложностей.

Ага. Если бы это не было сложно/сложно, мы бы не создавали нашу собственную модель; вместо этого мы бы покупали какое-то решение общего назначения у себя.

Грег Янг говорил об этом в презентации 2011 года: дизайн, ориентированный на домен, имеет смысл в тех местах, где мы можем получить конкурентное преимущество от выполняемой нами работы. Другими словами, мы используем его в тех местах, где предоставление бизнесу контроля над этой сложностью улучшает конечный результат.

Важным шагом является убедиться, что вы работаете на правильной стороне линии «сборка против покупки». Не пропускай это.