Говорят, что в CQRS легко исправить ошибку, вы просто повторно развертываете и затем воспроизводите события.
Но что, если одно из событий должно привести к тому, что внешняя система, не находящаяся под вашим контролем, «отправит товар» клиенту, если вы просто воспроизведите события, товар будет отправлен дважды.
Как вы решаете это?
Из статьи Мартина Фаулера о событиях :
Поэтому, когда вам нужно восстановить состояние вашей системы до определенного момента времени, вы воспроизводите сохраненное состояние , а не обработчики событий, до этого момента.
При этом, если вы работаете только с данными состояния, не должно быть никаких последствий для внешней системы. Если у вас нет триггеров или наблюдателей в вашем хранилище событий, в этом случае вы должны отключить их на время восстановления. Поскольку вы говорите, что не имеете никакого контроля над внешней системой, не должно быть никаких попыток восстановить ее состояние с помощью открытого API, поскольку вы не знаете, какие побочные эффекты могут иметь их системы. Если восстановление переводит систему в промежуточное состояние (например, из-за сбоя операций во внешней системе), это не должно входить в обязанности воспроизведения события.
источник
Чтобы выбрать конкретный пример, давайте рассмотрим, как может работать «хотя бы один раз» подход к побочным эффектам.
Таким образом, модель предметной области отслеживает, что необходимо сделать; но оставляет фактическое выполнение для приложения
В контексте выполнения команды основная идея выглядит одинаково. Фактические побочные эффекты происходят вне транзакции, которая обновляет модель.
Так что юнит-тесты для вашей модели могут выглядеть примерно так
Основными моментами здесь являются
источник