Как смоделировать проверку баланса счета? (Возможно ли это с возможной согласованностью / архитектурой, управляемой событиями?)

#domain-driven-design #event-driven-design

Вопрос:

Если есть 2 ограниченных контекста: Spending и Account management как предотвратить , чтобы пользователь не тратил больше, чем у него есть на балансе?

Я понимаю случай, когда у нас есть Order > Payment > Shipment последовательность для одного продукта, но здесь это больше похоже Order > Balance Check > Shipment , и я не понимаю, как проверить баланс в другом ограниченном контексте и быть уверенным, что пользователь никогда не потратит больше, чем у него есть.

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

[ОБНОВЛЕНИЕ] Я не упоминал, я думаю о решении в архитектуре, управляемой событиями, где ограниченные контексты обмениваются информацией только через события.

Ответ №1:

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

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

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

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

Чтобы еще больше усложнить, ваш процесс будет:

Заказ > Проверить Баланс >> Отправить >>> Списать средства.

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

Для этого я бы ввел понятие «целевого назначения» или «зарезервированных средств».

Таким образом, ваш контекст «Расходы» отправит запрос «резервные средства» в контекст «Менеджер по работе с клиентами» и будет ждать ответа. Этот ответ может включать идентификатор корреляции «резервирования средств». Вашей службе управления учетными записями потребуется понять понятия «фактический баланс» и «зарезервированные средства», чтобы рассчитать «доступный баланс».

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

Комментарии:

1. Требование: Не отправляйте товар, пока мы не узнаем, что клиент может заплатить. — спасибо, в частности, за это предложение! это открывает глаза. до сих пор я думал, например, не позволяйте клиенту делать заказ, пока мы не узнаем, что он может заплатить , но ваша формулировка намного лучше. и все остальное вытекает из этого естественным образом.

2. кроме того, я думаю, вы бы сохранили какое Order.Status -то поле в Spending BC, которое обновляется по мере того, как другие BC делают свои дела, верно?

3. Если вам это нужно для выполнения логики вашего домена, тогда да. Но не создавайте его только потому, что вы думаете, что это может быть полезно. Создавайте его, когда вам это нужно. ЯГНИ-это мощный инструмент.

4. ну, даже если это не для логики домена, а для чистого пользовательского интерфейса, чтобы информировать пользователя о статусе заказа (помимо отправки электронных писем для каждого события/шага). /кстати, на самом деле это оффтопические комментарии, поэтому пометьте их как ответ. Спасибо!

5. Я удалил свой последний комментарий, прочитав его про себя. Поддержание статуса канала для модели чтения-это нормально. Извините за путаницу.