Что такое двухфазный коммит
Что проверяют
Понимаете ли вы, почему атомарный коммит в нескольких базах это дорогая и хрупкая вещь, а не ещё одна аннотация @Transactional. Следом спрашивают, что будет, если координатор упадёт между фазами, и чем 2PC заменяют в микросервисах.
Как отвечать
Двухфазный коммит это протокол, который делает транзакцию в нескольких ресурсах (две базы, база и JMS-брокер) атомарной: применяется везде или нигде.
- фаза prepare: координатор просит участников подготовиться. Участник выполняет свою часть, пишет её в журнал на диск, держит блокировки и голосует «да» или «нет». Проголосовав «да», сам откатиться он уже не вправе;
- фаза commit: если все ответили «да», координатор фиксирует решение в своём журнале и рассылает commit, иначе rollback.
Главная слабость: протокол блокирующий. Если координатор упал после prepare, участники зависают в состоянии in-doubt, не могут ни закоммитить, ни откатить, и строки заблокированы до его возвращения. Плюс лишние сетевые обходы и скорость самого медленного участника.
В Java 2PC реализован через XA и JTA: ресурс отдаёт XAResource с методами prepare, commit, rollback, координирует менеджер транзакций вроде Narayana или Atomikos. В Spring Boot 3 стартер Atomikos не встроен, он подключается отдельно. В PostgreSQL за XA стоит PREPARE TRANSACTION, и по умолчанию он выключен: max_prepared_transactions = 0.
В микросервисах 2PC обычно избегают: Kafka XA не поддерживает, у HTTP-сервисов его нет. Вместо него берут сагу с компенсирующими действиями и transactional outbox: событие пишется в ту же локальную транзакцию, а доставляет его отдельный процесс или Debezium.
Где спотыкаются
Считают, что @Transactional с двумя DataSource даёт атомарность. Без JTA это две независимые локальные транзакции, а ChainedTransactionManager из Spring Data коммитит их по очереди и объявлен устаревшим: при сбое между коммитами данные расходятся.
Говорят, что 2PC повышает отказоустойчивость. Он даёт атомарность ценой доступности, а трёхфазный коммит сетевое разделение тоже не решает.
Приводят в пример межбанковские переводы. Там работают клиринг и сверки, а не распределённые блокировки между организациями.