Отображение изменений в представлении при использовании CQRS и DDD с событиями домена и ServiceBus - PullRequest
10 голосов
/ 06 октября 2010

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

Я надеюсь перевести дизайн одной из наших систем в соответствие с CQRS, используя события и служебную шину.

Допустим, мой поток выглядит так:

  1. Пользователь нажимает кнопку в представлении, чтобы выполнить задачу удаления способа оплаты со своей учетной записи.

  2. Контроллер вызывает PaymentMethodRemovalService, передавая ему accountId & paymentMethodId.

  3. Контроллер использует AccountRepository для извлечения учетной записи и вызывает account.RemovePaymentMethod (id)

  4. Аккаунт подтверждает, что операция может произойти, и публикует событие PaymentMethodRemovedMessage (accountId, paymentMethodId)

  5. Поскольку публикация событий является асинхронной, теперь мы должны вернуться из сервиса и вернуть представление из контроллера - , но наши фактические данные еще не обновлены !

  6. Обработчик IHandle , слышит событие и удаляет фактическую строку из БД

Итак, что делать парню?

Я мог бы просто, скажем, удалить div, который отображал способ оплаты. Это может работать в сценарии AJAX, но что, если я использую Post-Redirect-Get для поддержки клиентов не-JavaScript. Затем я буду запускать Get и читать данные со стороны Query, возможно, до того, как они обновятся.

Я просто показываю уведомление о том, что их запрос на удаление способа оплаты был отправлен? (что не кажется дружественным, имеет смысл для отправки заказа, но не для, скажем, изменения адреса).

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

РЕДАКТИРОВАТЬ: мой вопрос очень похож на CQRS, база данных отчетов о синхронизации DDD Я должен сказать, что ответ, данный там, а также здесь упоминается, имеет какой-то запах - спорят пользовательский интерфейс чтобы показать обновление, которое вне диапазона с прочитанной БД, так сказать. Я надеялся на что-нибудь немного чище.

Ответы [ 2 ]

8 голосов
/ 07 октября 2010

Если вы заблокированы в модели Запрос / Ответ, вы можете принять шаблон Сопоставленный запрос / ответ.За подробностями, ознакомьтесь с примером Async Pages в загрузке NSB.Это демонстрирует запрос / ответ в настройке ASP.NET.Есть несколько примеров ASP.NET MVC, если это больше подходит вам.

Когда вы вводите асинхронную обработку, вы соглашаетесь с тем, что данные устарели.Можно утверждать, что в момент запроса к БД данные уже устарели (задержка в сети, время рендеринга и т. Д.).Поскольку данные уже старые, мы должны спросить, сколько лет достаточно хорошо?

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

0 голосов
/ 22 июня 2017

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

Некоторое время назад я написал сообщение в блоге на эту тему, которое может оказаться полезным. Вы можете найти его здесь: 4 способа обработки возможной согласованности в пользовательском интерфейсе

Вот короткая версия:

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

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

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

В любом случае, надеюсь, что это даст пищу для размышлений.

...