Что делать, если событие домена не удалось?

Я новичок в ДДД. Теперь я смотрел на событие домена. Я не уверен, правильно ли я понимаю это событие домена, но я просто думаю, что произойдет, если событие домена не будет опубликовано?

У меня тут дело. Когда покупатель заказывает что-то на моем веб-сайте, сначала мы создаем объект «Заказ» с линейкой товаров. Событие домена OrderWasMade будет опубликовано для вычета запасов в Inventory. Итак, вот случай: что, если при обработке события количество товара будет вычтено, но что, если, когда система попытается вычесть запас, она обнаружит, что для товара не осталось запаса (сумма = 0) . Таким образом, сумма товара не может быть вычтена, но заказ уже совершен.

Произойдет ли такой сценарий?

Извините, что втиснул сюда еще 2 вопроса.

  1. Кажется, что каждое событие будет в своей области транзакции, что означает, что система требует одновременного открытия нескольких подключений к базе данных. Итак, если я использую IIS Server, я должен включить DTC, я прав?

  2. Есть ли какая-либо связь между доменными событиями и доменными службами?


comment
Похоже, Эрик Эванс и DDD никогда не слышали о ACID или менеджерах транзакций.   -  person duffymo    schedule 05.03.2016
comment
@duffymo Да, но решили, что им нужна более простая и удобная кодовая база. Кроме того, DDD является более высоким уровнем, чем ACID или менеджеры транзакций, которые являются деталями реализации. Один касается определения абстракции, другой — реализации частей этой абстракции.   -  person MikeSW    schedule 05.03.2016
comment
Иногда нужно быть КИСЛОТНЫМ. Я требую это от моего банка.   -  person duffymo    schedule 05.03.2016
comment
@duffymo ACID называется агрегатом в DDD.   -  person MikeSW    schedule 05.03.2016
comment
Готов поспорить, что больше людей знают, что такое ACID, чем DDD. Эрик Эванс написал прекрасную книгу, а потом напичкал ее таким количеством чепухи, что ее стало меньше. Я сидел с ним за обедом на конференции и сказал ему, что ему нужен редактор. Он согласился.   -  person duffymo    schedule 05.03.2016
comment
@duffymo Не секрет, что его книга довольно старая, а некоторые части устарели. Однако тактические шаблоны, такие как агрегаты или концепция настойчивого невежества, таковыми не являются.   -  person MikeSW    schedule 05.03.2016
comment
Некоторые из его идей хороши. Я не думаю, что он оказал большое влияние на среднего разработчика. Все знают шаблоны проектирования; немногие знают ДДД. Не влияет на повседневную практику кодирования.   -  person duffymo    schedule 05.03.2016
comment
@duffymo, это не потому, что сама книга или DDD такие громоздкие. Это потому, что среднестатистический разработчик не очень заинтересован в том, чтобы выходить за пределы своей зоны комфорта, разговаривать с клиентами, пытаться понять сферу их бизнеса. DDD эффективно устанавливает вездесущий язык в ограниченном контексте, и очень немногие разработчики действительно заинтересованы в этом.   -  person Alexey Zimarev    schedule 06.03.2016
comment
@Алексей Зимарев, я думаю, что часть вины лежит на книге. Шаблоны проектирования сделали это правильно; ДДД нет. Бьюсь об заклад, даже эти средние разработчики поймут, что вы имеете в виду, когда вы говорите «Одиночка» или «Фабрика», но они будут невежественны, когда вы скажете «агрегат». Они тоже будут знать КИСЛОТУ.   -  person duffymo    schedule 06.03.2016
comment
Что касается вашего примера с банком, я вдоволь посмеялся. Они, конечно, делают ACID внутри, но когда вы отправляете деньги в другой банк, они в конечном итоге исчезают с вашего счета, и проходит от нескольких минут до нескольких дней, прежде чем сумма действительно появится на счете получателя. Ты хоть представляешь, где твои деньги? Является ли он транзакционным в целом? Нет, он полагается на межбанковскую систему для завершения перевода, но вся операция не является ACID. Пользовательский интерфейс вашего интернет-банка в конечном счете также очень последователен, это очевидно.   -  person Alexey Zimarev    schedule 06.03.2016
comment
@duffymo Да, они могут быть невежественны, однако они могут быть невежественны во многих других вещах, я не вижу здесь корреляции. Разработчиков интересуют вещи, улучшающие их код, а DDD не касается кода. Еще одна особенность DDD — несоответствие импеданса, с которым было трудно справиться со всеми этими ORM, RDBMS и общей одержимостью ACID.   -  person Alexey Zimarev    schedule 06.03.2016
comment
Мне неинтересно обсуждать. Все основано на мнениях. Вот что я знаю: DDD не добился большого прогресса в распространении в обычную практику разработки программного обеспечения. Это не потому, что все на земле глупы. Это не было принято. Ты кажешься горьким по этому поводу. Почему это?   -  person duffymo    schedule 06.03.2016


Ответы (3)


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

Сценарий, который вы нам рассказали, показывает, что на самом деле вы не используете DDD, вы делаете CRUD, используя слова DDD. Да, я знаю, что вы новичок в этом, не волнуйтесь, все неправильно понимали DDD, пока не получили его (но это может занять некоторое время и много практики).

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

Далее, на этом уровне нет транзакций db/acid. Это детали реализации. Принцип работы DDD заключается в том, чтобы определить, где бизнесу нужно, чтобы вещи были согласованы друг с другом, и это называется совокупность.

Заказ был отправлен, и на этом прецедент останавливается. Когда вы публикуете OrderWasMadeevent, запускается другой вариант использования (вычет инвентаря или что-то еще). Это другой бизнес-сценарий, связанный, но не являющийся частью "отправки заказа". Если запаса недостаточно, публикуется другое событие NotEnoughInventory, и запускается другой вариант использования. Здесь мы следим за бизнесом и определяем каждый шаг, который делает бизнес для выполнения заказа.

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

В DDD совокупность — это единственное место, где необходимо использовать единицу работы.

Чтобы ответить на ваши вопросы:

Кажется, что каждое событие будет в своей области транзакции, что означает, что система требует одновременного открытия нескольких подключений к базе данных. Итак, если я использую IIS Server, я должен включить DTC, я прав?

Нет, транзакции, события и распределенные транзакции — это разные вещи. IIS — это веб-сервер, я думаю, вы хотите сказать SqlServer. Вы всегда открываете несколько подключений к базе данных в веб-приложении, DTC не имеет к этому никакого отношения. На самом деле вопрос говорит мне, что вам нужно больше читать о DDD, а не только книгу Эванса. Честно говоря, с точки зрения DDD не имеет особого смысла то, о чем вы спрашиваете. Вы знаете один из принципов DD: БД (как в деталях постоянства) не существует.

Есть ли какая-либо связь между доменными событиями и доменными службами?

Они оба являются частью домена, но у них разные роли:

  • События домена сообщают миру, что что-то изменилось в домене
  • Доменные службы инкапсулируют поведение домена, которое не имеет собственного сохраняемого состояния (например, Расчет налога).

Обычно служба приложения (которая действует как хост для бизнес-варианта) будет использовать службу домена для проверки ограничений или сбора данных, необходимых для изменения агрегата, который, в свою очередь, генерирует одно или несколько событий. Агрегаты - это те, которые сохраняются, и всегда агрегат сохраняется атомарным образом, то есть транзакция / единица работы БД.

person MikeSW    schedule 05.03.2016
comment
Если я правильно понимаю, если бизнес-процесс должен уведомить продавца об отсутствии на складе, событие NotEnoughInventory, скорее всего, будет выполнять эту работу уведомления. Если бизнес-процесс изменится, перед отправкой заказа система проверит наличие доступных запасов. Означает ли это, что у меня должна быть доменная служба для проверки запасов и разрешения отправки заказа при наличии запасов? - person Leonz; 06.03.2016
comment
Другой вопрос, почему DTC здесь не при чем? Поскольку каждый процесс (включая события) является собственной транзакцией, если процесс и событие происходят одновременно, одновременно будет 2 транзакции, и я считаю, что веб-приложение (без DTC) допускает только 1 транзакцию за раз. время (здесь происходит распределенная транзакция) - person Leonz; 06.03.2016
comment
@Leonz DTC - это очень специфическая деталь реализации, используемая для распределенных транзакций, которые сами по себе являются решением проблемы, которой не должно было существовать изначально. Если вы занимаетесь DDD, вы должны забыть о мышлении CRUD/ACID. Как я уже говорил, агрегат — это единица работы DDD, т. е. транзакция. Дело в том, что вы пытаетесь использовать слишком много вещей, которых пока не понимаете. Вам нужно понять, что DDD не имеет ничего общего с реализацией, и вам нужно понять архитектуру, управляемую сообщениями + CQRS. Не торопитесь, DDD, CQRS — это не рецепты, а парадигмы. - person MikeSW; 06.03.2016

что произойдет, если событие домена не будет опубликовано?

MikeSW уже описал это — публикация события (то есть включение его в историю) — это отдельная задача от потребления события.

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

Произойдет ли такой сценарий?

Итак, ответ DDD таков: спросите экспертов в своей области!

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

И когда вы понимаете эти требования, вы идете делать это.

Go do it обычно означает сагу (несколько вводящее в заблуждение и перегруженное использование термина); реализация бизнес-процесса / рабочего процесса / конечного автомата, которая отслеживает, что происходит.

Используя ваш пример: OrderWasMade запускает процесс OrderFulfillment, который отслеживает состояние заказа. Например, может быть состояние AwaitingInventory, в котором OrderFulfillment приостанавливается до следующей поставки от поставщика.

Рекомендуемое чтение:

person VoiceOfUnreason    schedule 05.03.2016

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

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

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

Другими словами, если ваш домен требует этого, вы можете торговать этой последовательностью событий.

(OrderAbortedOutOfStock)

за

(OrderMade, <-- Some amount of time --> OrderAbortedOutOfStock)

что равнозначно тому же агрегатному состоянию в конце

person guillaume31    schedule 07.03.2016