Как работать с распределенными транзакциями и не потерять данные
Связать разные микросервисы в одну жёсткую транзакцию равно утопии. Двухфазный коммит блокирует базы, копит задержки и намертво вешает систему, если падает координатор.
Единственный рабочий путь это итоговая согласованность через паттерн Сага. Процесс бьётся на цепочку локальных шагов, каждый сервис делает своё дело и кидает событие дальше. Если на середине пути случается сбой, запускаются компенсирующие транзакции, которые откатывают изменения назад вручную. Чтобы сеть не наштамповала дублей, все обработчики обязаны быть идемпотентными и отсекать повторные сообщения по уникальным ключам.
Главная точка потери данных попытка одновремнно обновить свою базу и отправить уведомление в брокер сообщений. Одно из двух обязательно упадёт. Проблема решается паттерном Transactional Outbox. Изменение данных и запись события сохраняются в родную базу одной локальной транзакцией, а уже отдельный фоновый процесс гарантированно перетаскивает это событие в очередь.
В распределённой среде данные выживают только тогда, когда вы изначально закладываетесь на худшее, внедряете сквозные Correlation ID для поиска концов, настраиваете умные повторные попытки (retry) и готовите админки для ручной сверки того, что не смогла разгрести автоматика.