Я прочитал различные ответы на этот и связанный с ним вопрос.
Решение сводится к правильности.Если вы можете простить и принять несовершенное поведение для некоторой степени операции, ваша проблема будет решена гораздо проще, особенно при слабых гарантиях согласованности.
Однако, если вы хотите согласованности, вы должны использовать службу сохранения, которая имеетстрогая согласованность гарантирует.
Например, команда, создающая короткий URL-адрес, проверит, что хранилище чтения уже не содержит такого короткого URL-адреса, и мы будем фиксировать наше событие, только если мы сможем зафиксировать изменения в нашемСначала прочитайте хранилище.
Если мы сможем зафиксировать наши изменения в нашем хранилище чтения, мы не нарушили какое-либо ограничение уникальности (при условии, что ваше хранилище чтения применяет такое ограничение), и мы можем продолжить.
Однако, поскольку у нас есть две транзакции, которые необязательно находятся в одной базе данных, мы можем потерпеть неудачу после первого принятия.Это нормально, потому что операция в целом также не будет выполнена.Хранилище чтения будет отражать несогласованное состояние в течение некоторого времени, но как только мы восстановим агрегат, хранилище чтения вернется в согласованное состояние.
В качестве процедуры обслуживания мы могли бы периодически восстанавливать агрегатыкоторые были подвержены потенциальным ошибкам.И вы можете сделать это, введя флаг ошибки, который сбрасывается только в случае успешной фиксации обеих транзакций.
Был пример, в котором банк позволил бы пользователю перезаписать свой счет, потому что у него есть доплаты, чтобы это компенсировать.Это вызывает вопросы, потому что решение такой проблемы может показаться небрежным, даже ленивым.Некоторые называют это умным.Я не знаю, что думать.У банка, вероятно, достаточно денег, чтобы покрыть его, поэтому они могли бы его игнорировать, но мир так не работает.В любом случае, я отвлекся.
С позиции правильности, наше хранилище чтения имеет надежную согласованность, и мы запишем нашу проекцию таким образом, что мы не сможем зафиксировать транзакцию в хранилище чтения, если баланс введен вотрицательныйТаким образом, самое худшее, что может произойти, это то, что из хранилища чтения вычитается заряд, но операция никогда не выполнялась полностью в хранилище событий.Пользователь будет видеть, что деньги отсутствуют на его счете, пока процедура обслуживания не заметит флаг ошибки и не вылечит учетную запись.Я думаю, что это рабочий компромисс.