При отказе координатора двухфазной транзакции после PREPARE почему участник не может самостоятельно завершить COMMIT?
Участник не может самостоятельно выбрать COMMIT, потому что после PREPARE он знает лишь о своей готовности, но не знает, подтвердили ли подготовку остальные участники и отправил ли координатор глобальное решение. Самостоятельный COMMIT может нарушить атомарность: один участник зафиксирует изменения, а другой отменит их.
Двухфазный протокол фиксации появился для координации атомарных изменений в нескольких независимых ресурсах: либо все участники фиксируют транзакцию, либо все откатывают её. Исходная проблема заключалась в том, что локально успешная операция ещё не означает возможность безопасно завершить распределённую транзакцию.
Протокол отделяет проверку готовности от окончательного решения. Это позволяет координатору принять единое решение, но создаёт зависимость участников от доступности координатора или механизма восстановления его состояния.
На фазе PREPARE участник обычно записывает состояние, достаточное для последующей фиксации, и обещает не принимать несовместимое решение. Однако он ещё не знает глобальный итог.
Если координатор выходит из строя перед отправкой финального решения, участник оказывается в неопределённости. Немедленный COMMIT может привести к частично зафиксированной транзакции, а немедленный ROLLBACK — к потере изменений, которые другие участники уже зафиксировали.
В первой фазе координатор запрашивает у всех участников готовность. Участник отвечает положительно только после локальной проверки ограничений и сохранения состояния, позволяющего выполнить фиксацию после сбоя.
Если все ответили положительно, координатор принимает решение COMMIT, сохраняет его устойчиво и рассылает участникам. Если хотя бы один участник ответил отрицательно, принимается ROLLBACK.
После положительного PREPARE участник не может безопасно отменить транзакцию по собственной инициативе: другой участник мог уже получить команду COMMIT. Аналогично, он не может сам зафиксировать изменения, потому что остальные могли не быть готовы.
Это называется блокирующим свойством 2PC. Участник может удерживать блокировки и ждать восстановления координатора, чтения его журнала или решения через процедуру восстановления.
2PC не является консенсусом. Он координирует атомарность при предполагаемой возможности восстановить координатора, но не гарантирует доступность при произвольных сбоях и сетевых разделениях. Добавление резервного координатора не решает задачу само по себе: резерв должен достоверно узнать устойчиво принятое решение, иначе два координатора могут выдать противоречивые команды.
Основной компромисс таков: 2PC обеспечивает атомарность распределённой транзакции, но платит задержкой, удержанием ресурсов и возможной блокировкой при отказе координатора. Для уменьшения ущерба применяют устойчивый журнал решений, процедуру восстановления, ограничение времени ожидания на внешнем уровне или более сложные протоколы, например трёхфазную фиксацию либо согласование решения через консенсус.
Платёжный сервис резервирует деньги, а складской сервис резервирует товар. Платёж успешно подготовлен, склад также ответил PREPARE, после чего координатор упал до рассылки финального решения.
Вариант с немедленным откатом быстро освобождает ресурсы, но может противоречить уже отправленной команде фиксации, если координатор успел записать её или доставить её одному участнику. Вариант с немедленной фиксацией быстрее восстанавливает доступность, но может оставить деньги списанными без резерва товара.
Безопасное решение — сохранить подготовленные состояния, восстановить журнал координатора или получить решение через согласованный отказоустойчивый механизм. Пока итог не установлен, участники временно удерживают резерв; результатом становятся атомарность операции и повышенная задержка восстановления.
1. Вопрос: Почему тайм-аут участника после PREPARE не позволяет безопасно выбрать ROLLBACK?
Тайм-аут сообщает лишь об отсутствии ответа, но не о принятом глобальном решении. Координатор мог отправить COMMIT, а сообщение могло задержаться в сети. Поэтому тайм-аут может инициировать процедуру восстановления, но не является доказательством права на откат.
2. Вопрос: Что должен проверить новый координатор перед продолжением транзакции?
Он должен определить, было ли глобальное решение устойчиво записано, и собрать состояния участников. Если решение COMMIT уже подтверждено журналом, его нужно довести до всех участников. Если часть участников находится в состоянии PREPARE, а окончательное решение не зафиксировано, новый координатор обязан действовать по правилам протокола, не выбирая произвольный исход, который может нарушить атомарность.
3. Вопрос: Почему превращение координатора в реплицируемый сервис не устраняет проблему автоматически?
Репликация координатора полезна только при согласованном порядке записи решения и при гарантии, что новый лидер не выдаст противоречивое решение. Если несколько координаторов могут независимо считать себя активными, возникает риск двойного руководства. Поэтому отказоустойчивый координатор обычно опирается на журнал, выбор лидера и механизм консенсуса; это снижает риск потери решения, но не отменяет задержки и затрат самой распределённой транзакции.