Какие есть способы поддержания консистентности данных в распределенной системе микросервисов и как решать проблему отката изменений
Что проверяют
Понимаете ли вы, что распределённой транзакции не будет, и знаете ли, чем компенсация отличается от отката.
Как отвечать
Начните с ограничения: у каждого сервиса своя база, поэтому обычная транзакция невозможна. Двухфазное подтверждение технически существует, но в микросервисах его избегают: оно блокирует участников на время согласования и плохо переживает падение координатора.
Что используют вместо этого:
1. Сага. Операция разбивается на цепочку локальных транзакций, у каждой есть компенсирующее действие. Сбой на третьем шаге запускает компенсации первых двух в обратном порядке. Координация бывает через события (хореография) или через явный координатор (оркестрация). На трёх шагах проще первое, дальше выгоднее второе, потому что сценарий виден в одном месте.
2. Транзакционный ящик исходящих. Запись в базу и публикация события делаются атомарно: событие пишется в ту же базу той же транзакцией, а отдельный процесс отправляет его в брокер. Без этого запись и публикация однажды разойдутся, и данные разъедутся навсегда.
3. Идемпотентность. Доставка сообщений даёт повторы, поэтому обработчик обязан выдерживать повторное выполнение. Обычно через ключ операции или уникальный индекс.
4. Оптимистичная блокировка по версии записи, чтобы параллельные изменения не затирали друг друга.
Теперь про откат, ради чего вопрос и задают. Компенсация это не откат. Откат стирает следы, компенсация выполняет обратное действие: деньги возвращаются новой операцией, а письмо «заказ принят», если оно уже ушло, отозвать невозможно. Отсюда правила:
- некомпенсируемые шаги ставят в конец цепочки, когда всё остальное уже подтверждено;
- промежуточное состояние делают явным: статус «в обработке» вместо вида завершённой операции;
- компенсации тоже идемпотентны и тоже могут упасть, поэтому нужны повторы и оповещение о зависших сагах;
- разбор вручную это штатный сценарий, а не признак плохой системы. Нужен инструмент, показывающий незавершённые операции.
Где спотыкаются
Считают сагу заменой транзакции с теми же гарантиями.
Публикуют событие после фиксации транзакции отдельным вызовом.
Не продумывают отказ самой компенсации.
Показывают пользователю завершённую операцию до подтверждения всей цепочки.