462. 2단계 커밋 (2PC - Two-Phase Commit)
⚠️ 이 문서는 서울 서버와 뉴욕 서버에 동시에 똑같은 데이터를 안전하게 저장하기 위해, **모든 서버가 100% 준비되었는지 확인한 다음에야 동시에 확정 도장(Commit)을 찍게 만드는 분산 트랜잭션의 고전적인 동기화 기술인 '2PC'**를 다룹니다.
핵심 인사이트 (3줄 요약)
- 본질: 분산된 여러 데이터베이스가 모두 동의해야만 트랜잭션을 완료(Commit)하고, 한 명이라도 반대하면 전체를 취소(Rollback)하는 만장일치 합의 프로토콜이다.
- 작동 방식: 중앙의 코디네이터(Coordinator)가 "너희들 준비됐니?(Prepare)"라고 묻는 1단계와, 전원이 OK 했을 때 "다 같이 도장 찍어!(Commit)"라고 명령하는 2단계로 나뉜다.
- 한계: 한 대의 서버만 네트워크가 끊기거나 응답이 늦어져도 전체 시스템이 멈춰버리는(Blocking) 치명적인 단점이 있어, 클라우드(MSA) 시대에는 점차 사가 패턴(Saga Pattern, 550번 문서)으로 대체되고 있다.
Ⅰ. 개요: 만장일치의 원칙 (Context & Necessity)
"A 계좌(한국)에서 B 계좌(미국)로 1만 달러를 이체하라."
만약 한국 서버는 돈을 뺐는데(COMMIT), 미국 서버는 정전으로 돈을 못 넣었다면(ROLLBACK)? 1만 달러가 우주로 증발한다.
분산 데이터베이스는 이런 끔찍한 일관성 파괴를 막기 위해, 모든 서버가 한 몸처럼 움직이길 원했다. **2단계 커밋(2PC)**은 이름 그대로 커밋을 두 번에 나눠서 조심스럽게 진행한다.
- 1단계: "한국! 돈 뺄 준비(Lock) 다 됐어?", "미국! 돈 넣을 준비(Lock) 다 됐어?"
- 2단계: "둘 다 준비 완벽하네. 그럼 지금 당장 동시에 COMMIT 쳐!"
📢 섹션 요약 비유: 2PC는 **'결혼식 주례'**와 같습니다. 주례사 선생님(코디네이터)이 신랑과 신부에게 "서로 사랑하겠습니까?"라고 묻고(Prepare), 둘 다 "네!"라고 100% 대답했을 때만 비로소 부부임을 선포(Commit)하죠. 신랑이 "아니오"라고 하거나 대답 전에 기절해 버리면 그 결혼식은 통째로 무효(Rollback)가 됩니다.
Ⅱ. 2PC의 2단계 작동 원리 ★
코디네이터(Coordinator)와 참여자(Participant) 간의 대화 흐름이다.
1단계: 준비 단계 (Prepare Phase / Voting)
- 코디네이터가 모든 참여자(한국 DB, 미국 DB)에게 "트랜잭션을 수행할 준비가 되었는가?"라고
PREPARE메시지를 쏜다. - 각 참여자는 자신이 맡은 쿼리를 실행하고, 디스크에 임시로 써둔 뒤, 자물쇠(Lock)를 꽉 쥐고서 "나 준비 완료!(VOTE_COMMIT)" 또는 "나 에러 났어!(VOTE_ABORT)"라고 대답한다.
2단계: 실행 단계 (Commit Phase / Decision)
- 코디네이터가 투표 결과를 집계한다.
- 성공(Commit): 모든 참여자가
VOTE_COMMIT을 보냈다면, "전원COMMIT하라!"고 명령을 내린다. - 실패(Rollback): 단 한 명이라도
VOTE_ABORT를 보내거나(반대), 타임아웃 시간 내에 대답을 안 하면(무응답), "전원ROLLBACK하라!"고 명령을 내린다.
Ⅲ. 2PC의 3가지 치명적 단점 (Blocking 문제)
2PC는 이론적으로는 완벽하지만 현실 세계(클라우드)에서는 지옥을 만든다.
1. 대기 시간(Blocking)과 성능 저하
- 한국 DB는
PREPARE를 끝내고 자물쇠(Lock)를 쥔 채로 코디네이터의 다음 명령을 기다린다. - 미국 DB가 대답을 1분 늦게 하면? 한국 DB의 자물쇠도 1분 동안 안 풀린다. 다른 사람들은 한국 DB를 못 쓰고 다 같이 멈춰있는다.
2. 코디네이터의 단일 장애점 (SPOF)
- 만약 한국과 미국이 모두 "준비 완료!"라고 대답했는데, 갑자기 코디네이터 서버가 벼락을 맞아 죽어버리면?
- 한국과 미국 서버는 코디네이터가 살아날 때까지 영원히 자물쇠를 쥐고 무한 대기 상태(Deadlock)에 빠진다.
3. 확장성(Scalability) 부족
- 서버가 2대일 땐 할 만하다. 하지만 마이크로서비스(MSA)에서 서버가 10대가 엮여있다면?
- 10대 중 1대만 네트워크가 느려도 트랜잭션 성공률이 바닥으로 꽂힌다.
┌──────────────────────────────────────────────────────────────┐
│ 2PC (Two-Phase Commit)의 작동 흐름 및 병목 시각화 │
├──────────────────────────────────────────────────────────────┤
│ │
│ [ 👨⚖️ 코디네이터 ] │
│ │ │
│ ├── 1. "준비해(Prepare)!" ──▶ [ 🇰🇷 한국 DB ] 🔒 락 걸고 대기 │
│ │ │
│ ├── 1. "준비해(Prepare)!" ──▶ [ 🇺🇸 미국 DB ] 🐢 (네트워크 느림)│
│ │ │
│ ⏳ (코디네이터는 미국 DB가 대답할 때까지 무한 대기) │
│ │ │
│ ├── 2. "전원 Commit!" ──▶ [ 🇰🇷 한국 DB ] 🔓 드디어 락 해제 │
│ │ ──▶ [ 🇺🇸 미국 DB ] 🔓 드디어 락 해제 │
│ │
│ ★ 특징: 가장 느린 서버(미국)의 속도가 전체 트랜잭션의 속도가 되어버린다. │
└──────────────────────────────────────────────────────────────┘
Ⅳ. 결론
"완벽을 고집하면 시스템은 부러진다." 2PC는 '완벽한 강한 일관성(Strong Consistency)'을 요구하는 분산 시스템에서 어쩔 수 없이 써야 하는 필요악이다. 하지만 클라우드 네이티브 환경에서 "네트워크는 항상 끊어지고 서버는 항상 죽는다"는 진리가 퍼지면서, 2PC의 빡빡한 만장일치 원칙은 시스템의 가용성(Availability)을 너무 많이 훼손한다는 비판을 받게 되었다. 오늘날 MSA 환경에서는 이 낡은 기술 대신, 일시적인 불일치를 허용하면서 락(Lock) 없이 각자 갈 길을 가는 유연한 '사가 패턴(Saga Pattern, 550번 문서)'이 분산 트랜잭션의 새로운 왕좌를 차지하고 있다.
📌 관련 개념 맵
- 관련 특성: 분산 트랜잭션 (Distributed Transaction), 원자성 (Atomicity - 441번)
- 대안 패턴: Saga Pattern (550번), Eventual Consistency (결과적 일관성)
- 발생 문제점: Blocking (무한 대기), SPOF (단일 장애점)
- 개선된 프로토콜: 3PC (Three-Phase Commit - 코디네이터가 죽었을 때를 대비해 상태를 공유하는 단계를 추가한 기술)
👶 어린이를 위한 3줄 비유 설명
- 2PC는 친구 5명이 손을 잡고 건널목을 건너는 것과 같아요.
- 반장(코디네이터)이 "애들아 건널 준비 다 됐어?" 하고 5명 모두에게 물어보죠. 한 명이라도 신발 끈을 묶고 있으면 모두 출발을 못 하고 기다려야 해요. (성능 저하)
- 모두 "준비 끝!"이라고 외치면, 반장이 "자, 출발!" 하고 5명이 동시에 발을 내디뎌야 하는 아주 깐깐하고 답답한 규칙이랍니다!