Что такое двухфазный коммит для распределенных транзакций
Что проверяют
Понимаете ли вы, как добиться атомарности на нескольких ресурсах и чем за это платят. Для Java следом почти всегда спрашивают про XA и JTA, а в микросервисной части про то, почему там выбирают саги.
Как отвечать
В протоколе есть координатор (менеджер транзакций) и участники (базы, брокеры):
- фаза prepare: координатор просит всех подготовиться. Участник записывает изменения в надёжный журнал, держит блокировки и голосует «да» или «нет». Проголосовав «да», он теряет право решать сам и ждёт вердикта;
- фаза commit: если все ответили «да», координатор фиксирует решение в своём журнале и рассылает commit, иначе rollback всем.
Гарантия: либо изменения применили все, либо никто. Цена: минимум два сетевых круга, блокировки удерживаются до конца второй фазы, а падение координатора после голосования оставляет участников в состоянии in-doubt с захваченными блокировками, пока он не восстановится. Поэтому 2PC называют блокирующим протоколом. 3PC снимает её лишь при допущении об ограниченных сетевых задержках и на практике почти не встречается.
В Java это стандарт XA и JTA: интерфейс XAResource с методами prepare, commit, rollback, recover, API jakarta.transaction.UserTransaction и TransactionManager. Менеджеры транзакций: Narayana в WildFly и Quarkus, Atomikos как встраиваемый вариант. В Spring это JtaTransactionManager и обычная @Transactional. Базе нужна поддержка: в PostgreSQL это PREPARE TRANSACTION, а по умолчанию max_prepared_transactions равен нулю.
В микросервисах, связанных по HTTP, 2PC обычно недоступен и нежелателен. Там используют Saga с компенсирующими действиями и Transactional Outbox, соглашаясь на итоговую согласованность.
Где спотыкаются
Утверждают, что 2PC гарантирует согласованность при любом сбое, и не упоминают блокировку при падении координатора.
Считают, что ChainedTransactionManager из Spring даёт распределённую транзакцию. Он лишь коммитит ресурсы по очереди, и сбой между коммитами оставит данные рассогласованными. Сам класс давно помечен устаревшим.
Путают сагу с 2PC и говорят, что сага даёт изоляцию. Промежуточные состояния саги видны другим, и это учитывают в бизнес-логике.