Ответ
Двухфазный коммит (2PC) — это протокол координации, гарантирующий атомарность транзакции в распределённой системе (например, между несколькими базами данных или микросервисами). Он обеспечивает, чтобы все участники либо зафиксировали изменения, либо выполнили откат.
Фазы протокола:
-
Фаза подготовки (Prepare)
- Координатор отправляет всем участникам команду
prepare. - Каждый участник выполняет локальные операции транзакции, блокирует ресурсы и записывает данные в лог, но не фиксирует.
- Участник голосует: отправляет координатору
YES(готов) илиNO(не готов / ошибка).
- Координатор отправляет всем участникам команду
-
Фаза фиксации (Commit/Rollback)
- Если все участники ответили
YES: координатор отправляет командуcommit. Участники фиксируют изменения и освобождают ресурсы. - Если хотя бы один участник ответил
NO: координатор отправляет командуrollback. Все участники откатывают изменения.
- Если все участники ответили
Пример псевдокода:
// Координатор
boolean allPrepared = participants.stream()
.allMatch(p -> p.prepare(transactionData));
if (allPrepared) {
participants.forEach(p -> p.commit(transactionId));
} else {
participants.forEach(p -> p.rollback(transactionId));
}
Ключевые проблемы 2PC:
- Блокировки ресурсов: Участники блокируют данные на время всего протокола, что снижает производительность.
- Отказ координатора: Если координатор выходит из строя после фазы подготовки, участники остаются в заблокированном состоянии (проблема подвешенной транзакции).
- Синхронное ожидание: Протокол является синхронным и блокирующим.
Альтернативы: Для повышения доступности и производительности используют протоколы вроде трёхфазного коммита (3PC) или паттерн Saga (компенсирующие транзакции).