9

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

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

Скажем, мой поток идет, как, например:

  1. Пользователь кнопку защелкивается View для выполнения задачи удаления Способ оплаты с их счета.

  2. Контрольные вызовы PaymentMethodRemovalService, передача его accountId & paymentMethodId.

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

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

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

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

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

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

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

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

EDIT: Мой вопрос очень похож на CQRS, DDD synching reporting database я должен сказать, что ответ дается там и также упоминается здесь, имеет немного запах к нему - пререканиям интерфейса, чтобы показать обновление, которое находится вне диапазона с прочитанный БД, так сказать. Я надеялся на что-то немного чище.

ответ

8

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

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

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

0

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

A while back Я написал сообщение в блоге по этому вопросу, которое может оказаться полезным. Вы можете найти его здесь: 4 Ways to Handle Eventual Consistency on the UI

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

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

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

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

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