Мое первое впечатление заключается в том, что всякий раз, когда вам нужна согласованность транзакций между агрегатами, вы неправильно спроектировали агрегаты.
Совершенно верно; способ, которым вы обнаруживаете границы агрегирования, состоит в том, чтобы сначала определить значения, которые необходимо поддерживать согласованными, а затем выбрать границы, которые обладают свойством, согласно которому любые два значения, которые должны быть согласованы друг с другом, находятся в пределах одной границы.
Примечание: мы не всегда понимаем это правильно; возможно, требования были неправильными, возможно, наша модель не соответствовала требованиям, возможно, изменился бизнес. Отчасти задача состоит в том, чтобы всегда легко заменить текущую модель на более качественную.
На основе этой информации вы можете создать три агрегата: «Корова», «Запас» и «Заказ».
Примечание: Cow
- паршивая совокупность - если предположить, что мы говорим о настоящих в мире поедающих травяных коровах. Да, это сущность, но она находится вне влияния модели. Если модель говорит, что корова пуста, а корова говорит, что она полна молока, корова права.
Точно так же, если коровы настоящие, то большая часть вашего поголовья также настоящая. Если модель говорит, что есть семь полных канистр молока, а фермер считает шесть, то шесть - правильный ответ.
Агрегаты - это информационные ресурсы.
Каждый раз, когда заказывается определенное количество молока, одно из бизнес-правил - проверять, есть ли это количество в наличии, а если нет, сразу же сообщать пользователю. Как этого добиться, если два пользователя одновременно запрашивают и заказывают 150 литров молока, в то время как доступно только 130 литров?
Важно понимать, что «сразу»; вы здесь, пользователь (покупатель?) там. Связь имеет определенную задержку, а это означает, что информация, которую вы отправляете покупателю, уже устарела, когда она поступает. (Технически он уже устарел на момент отправки.)
Во-вторых, выполнение заказов требует понимания как заказов, так и наличия на складе. Таким образом, вы можете смоделировать это как единый агрегат, который делает все, или вы можете смоделировать его как агрегаты заказов, которые асинхронно взаимодействуют с некоторым агрегатом выполнения; например, может случиться так, что на самом деле Stock сопоставляет уведомления о доступном молоке с отложенными заказами.
В вашем примере параллельной обработки это будет выглядеть как две команды для резервирования 130 литров молока, работающих одновременно с агрегатом запаса, имеющим 150 литров молока. Используя оптимистичный параллелизм, обе команды обнаружат, что молока достаточно для удовлетворения заказа, и попытаются обновить книгу записей. Однако это обновление сериализуется - подумайте о транзакции или сравните и поменяйте местами - поэтому одна из команд выполняется успешно, а другая вместо этого получает исключение одновременной модификации. Таким образом, эта вторая команда пытается еще раз, перезагружая ложу в ее новом состоянии. На этот раз он обнаруживает, что имеющихся запасов недостаточно, и действует соответствующим образом (перемещает заказ в список ожидания, уведомляет покупателя об ожидаемой дате выполнения и т. Д.).
Обратите внимание, что вы также получите исключения одновременной модификации, когда команда резервирования молока запускается параллельно с объявлением о том, что доступно больше молока.
person
VoiceOfUnreason
schedule
04.04.2017
Cow
иStock
в один агрегат? Кажется, это те части, которые вам нужно постоянно поддерживать. На мой взгляд, нет необходимости моделироватьCow
как отдельный агрегат. - person Mike Wojtyna   schedule 04.04.2017Cow
иStock
в один агрегат, поскольку бизнес требует, чтобы это было согласовано. - person Frank Levering   schedule 04.04.2017