549. 2PC (Two-Phase Commit)의 MSA 적용 한계

핵심 인사이트 (3줄 요약)

  1. 본질: 2PC(Two-Phase Commit)는 분산된 2개 이상의 DB를 1대의 통짜 DB처럼 완벽하게 동기화하기 위해, 코디네이터(지휘자)가 모든 DB에 "준비해!(Prepare)" ➡ "쏴!(Commit)"라는 2단계 자물쇠(Lock)를 강제로 채우는 극단적 무결성(Consistency) 맹신 아키텍처다.
  2. 가치: 클라우드가 없던 온프레미스(On-premise) 랜선 시대에는 금융권의 돈을 지켜주는 든든한 신(God)이었다. 하지만 네트워크가 1초에도 수십 번 끊기고 노드가 죽어 나가는 현대 마이크로서비스(MSA) 클라우드 환경에서는 하나의 DB가 대답하지 않으면 전사 시스템이 락(Lock)에 걸려 얼어붙는 파멸적 단일 장애점(SPOF)으로 전락한다.
  3. 융합: CAP 정리에서 완벽히 CP(Consistency & Partition tolerance) 속성을 대변하며, 클라우드의 생명인 가용성(Availability)을 박살 내기 때문에 최악의 분산 모놀리스(Distributed Monolith, 537장) 안티패턴으로 버려지고, 이를 타파하기 위해 **사가 패턴(Saga Pattern, 550장)**과 BASE 사상이 MSA의 뉴노멀로 융합 등극하게 된다.

Ⅰ. 개요 및 필요성 (Context & Necessity)

  • 개념: "결제 DB에서 -1만 원", "배송 DB에서 재고 -1개". 이 두 쿼리가 다른 서버(DB)에 있을 때, 둘이 손을 잡고 "동시에 같이 저장되거나, 동시에 취소(Rollback)되게" 멱살을 잡는 통제 프로토콜이 2PC(Two-Phase Commit)다. 이름 그대로 트랜잭션을 1단계(준비/Lock)와 2단계(확정/해제)로 쪼개어 억지로 타이밍을 맞춘다.

  • 필요성(탄생 배경): 모놀리식 시절에는 DB가 1대라 오라클(Oracle) 엔진이 트랜잭션을 알아서 막아줬다. 그런데 회사가 커지면서 DB를 2개로 물리적으로 쪼개버렸다. 분산 DB 환경에서도 "우린 1원도 틀리면 안 돼!"라는 금융권의 똥고집이 X/Open XA라는 글로벌 2PC 표준 규격을 만들어냈다. 코디네이터(Transaction Manager) 서버를 하나 더 띄우고, 이 놈이 모든 DB를 감시하게 만든 강제 동기화의 서막이다.

  • 💡 비유: 2PC는 수십 명이 참여하는 **'결혼식 단체 만세 삼창'**과 같습니다. 코디네이터(사회자)가 "다들 두 손 위로 올려서 준비하세요!(Prepare)"라고 소리칩니다. 한 명이라도 손을 안 올리면 사회자는 영원히 "손 올리세요!"라고 기다리며 만세를 안 부릅니다(Blocking). 모두가 손을 올린 게 100% 확인되면 그제야 "만세!(Commit)"를 외칩니다. 만약 중간에 한 놈이 화장실에 가서 10분 동안 안 돌아오면, 나머지 99명은 10분 동안 팔을 들고 땀을 뻘뻘 흘리며 얼어붙은 채 기다려야 합니다(Lock 경합/리소스 고갈).

  • MSA 시대의 몰락 과정:

    1. 온프레미스 시대 (신뢰망): 사내 전산실은 네트워크가 끊길 일이 거의 없어서 2PC가 쌩쌩 잘 돌았다. (성공률 99.9%)
    2. 클라우드 / MSA 찢기 시대 (의심망): 앱을 50개로 찢고 AWS 클라우드에 올렸다. AWS는 1초에도 수백 번씩 마이크로 지연과 네트워크 단절(Partition)이 일어난다.
    3. 파멸적 셧다운: 2PC 코디네이터가 50개 DB에 락(Lock)을 걸었는데 1개 DB가 네트워크에 걸려 3초간 먹통이 됐다. 3초 동안 전사의 모든 DB 스레드가 락이 풀리기만을 기다리다가(Thread Pool Exhaustion) 쇼핑몰 전체가 하얗게 뻗어버리는 대참사가 반복되며 2PC는 클라우드의 절대 악으로 규정되었다.
  • 📢 섹션 요약 비유: 2PC는 **'모든 차선의 차량이 100% 정지한 것을 확인한 뒤에만 출발 신호를 켜는 구석기 수동 신호등'**입니다. 안전(무결성)은 100점이지만, 꼬리물기 차량 1대만 있어도 신호등이 파란불을 절대 안 켜주기 때문에 서울 시내 전체 교통이 마비(가용성 제로)되는 융통성 0점의 시스템입니다.


Ⅱ. 아키텍처 및 핵심 원리 (Deep Dive)

1. 2PC의 동작 메커니즘 (2단계 구조)

트랜잭션 코디네이터(TC)와 2대의 분산 DB(결제, 재고) 간의 통신 시퀀스.

[ 🛡️ Phase 1: Prepare (준비 및 자물쇠 채우기) ]

  1. TC(코디네이터)가 결제 DB와 재고 DB에 "트랜잭션 준비(Prepare)해!" 명령을 쏜다.
  2. 각 DB는 자기가 이 쿼리를 처리할 수 있는지 검사하고, 데이터에 강력한 락(Exclusive Lock)을 건다. (다른 앱은 이 데이터 건드리지도 못함)
  3. 두 DB가 모두 "준비 완료(Ready/Vote Commit)" 응답을 TC에게 반환한다.

[ 💥 Phase 2: Commit or Rollback (실행 또는 취소) ]

  • 시나리오 A (둘 다 Ready 온 경우): TC가 "오케이, 둘 다 Commit 해!" 명령을 쏜다. 둘 다 데이터를 디스크에 쓰고 락을 푼다. (해피 엔딩)
  • 시나리오 B (한 놈이라도 에러 뱉거나 응답 시간 초과 시): 재고 DB가 "나 재고 없어서 에러 났어(Abort)!" 뱉는다. TC는 결제 DB에 "방금 락 걸어둔 거 다 풀어! 취소(Rollback)해!" 명령을 쏴서 둘 다 원상태로 돌린다.

2. 2PC가 MSA에서 멸망한 3대 아킬레스건 (핵심 한계)

면접에서 "왜 2PC 쓰면 안 되나요?"에 대한 100점짜리 답변.

  1. 동기 블로킹(Synchronous Blocking)의 저주: Phase 1에서 락(Lock)을 건 순간부터 Phase 2가 끝날 때까지, **데이터는 완벽히 동결(Blocked)**된다. 코디네이터가 뻗거나(SPOF), 네트워크가 느려져 10초 딜레이가 걸리면? 다른 수만 명의 사용자들은 그 DB 레코드(Row)에 접근하지 못하고 무한 대기에 빠지며 시스템 전체가 썩어 들어간다.
  2. 단일 장애점 (SPOF, Single Point of Failure): 2PC는 철저하게 코디네이터(TC) 1명의 지휘에 목숨을 건다. Phase 1(준비)을 끝내고 각 DB가 락을 꽉 쥐고 있는데, 하필 그 찰나에 코디네이터 서버가 죽어버렸다? DB들은 "야 우리 Commit 해 말어?" 물어볼 데가 없어 락을 풀지도 못하고 평생 굳어버린다(Heuristic Exception 지옥).
  3. NoSQL / 최신 DB들의 지원 포기: MongoDB, Cassandra, 심지어 Kafka 같은 현대 분산 툴들은 "가용성(Availability)"을 살리기 위해 애초에 설계 바닥부터 XA(2PC) 프로토콜 지원을 포기하거나 버렸다. 즉, 2PC를 쓰고 싶어도 쓸 툴이 없는 시대가 왔다.
  • 📢 섹션 요약 비유: Phase 1의 락(Lock)은 **'숨참기'**와 같습니다. 코디네이터가 "다 같이 숨 참아!(Prepare)" 하고 모두가 숨을 참고 있습니다. 그다음 코디네이터가 "이제 숨 쉬어!(Commit)" 해야 하는데, 코디네이터가 화장실에 가버렸습니다(SPOF 에러). 그럼 남아있는 DB들은 명령이 올 때까지 계속 숨을 참다가 산소 부족(리소스 고갈)으로 단체로 기절해 버리는 구조적 결함 덩어리입니다.

Ⅲ. 융합 비교 및 다각도 분석

1. CAP 정리로 본 2PC vs Saga (무결성 vs 가용성)

척도2PC (Two-Phase Commit) 🔒사가 패턴 (Saga Pattern) 🏃
CAP 속성CP (Consistency 중심)AP (Availability 중심 + Eventual Consistency)
처리 방식동기식(Sync), 응답 올 때까지 대기비동기식(Async), 메시지 큐(Kafka)로 툭 던짐
에러 수습법물리적 Rollback (애초에 저장을 안 함)논리적 보상(Compensation) (일단 저장하고 나중에 -1 쳐서 환불함)
DB 락(Lock)전역 자물쇠(Global Lock) 100% 점유락 없음(Lock-Free), 지 로컬 DB만 잠시 썼다 푸름
클라우드 궁합최악 (네트워크 지연 시 전사 셧다운)최상 (MSA 50개 서버 찢기의 구세주)

과목 융합 관점

  • 클라우드 / MSA 아키텍처 (안티패턴: 분산 모놀리스): 537장에서 다룬 최악의 아키텍처다. 회사는 수억을 들여 K8s에 파드(Pod)를 50개로 예쁘게 찢어 MSA를 구현했다. 그런데 트랜잭션 관리가 무서워서 2PC를 도입해 버렸다? 50개의 서비스가 동기(Sync) 네트워크 통신과 락(Lock)으로 거미줄처럼 한 몸으로 묶여버렸다. 결국 1개 파드가 뻗으면 50개 파드가 도미노로 뻗는 '찢어놓은 의미가 0인 괴물(Distributed Monolith)'이 탄생하며 클라우드의 유연성(Agility)이 박살 난다.

  • 운영체제 (교착상태, Deadlock): 2PC는 OS의 영원한 숙제인 데드락의 폭발 위험을 분산 네트워크 레벨로 스케일업시킨 것이다. A 트랜잭션이 결제 DB ➡ 재고 DB 순으로 락을 잡고, B 트랜잭션이 재고 DB ➡ 결제 DB 순으로 2PC 락을 잡으려 시도하면 전 우주적인 데드락이 발생하여 두 트랜잭션이 영원히 서로를 노려보며 멈추는 비극이 매초 단위로 일어난다.

  • 📢 섹션 요약 비유: 2PC를 고집하는 것은 **'달리기 계주 릴레이'에서 바통(데이터)을 넘길 때, 1번 주자와 2번 주자가 손목에 수갑(Global Lock)을 채우고 같이 뛰는 멍청한 짓'**입니다. 1번 주자가 넘어지면 2번 주자도 같이 자빠집니다. 클라우드 시대(Saga)는 수갑을 끊어버리고 바통을 던지며 각자 알아서 빛의 속도로 달리는 것입니다. 바통을 떨어뜨리면 멈춰서 수습(보상 트랜잭션)하더라도 절대 발을 묶어 시스템 전체 속도를 죽이지 않습니다.


Ⅳ. 실무 적용 및 기술사적 판단

실무 시나리오

  1. 시나리오 — 낡은 금융권 코어 뱅킹의 JTA/XA 2PC 고집이 부른 대재앙: 대형 은행이 차세대 계정계 프로젝트를 MSA로 찢었다. 그런데 60대 수석 아키텍트가 "돈이 1원이라도 비면 감옥 간다! 무조건 100% 정합성 지켜!"라며 JTA(Java Transaction API) 기반 XA 2PC 프로토콜을 50개 마이크로서비스 전체에 강제 적용했다. 오픈 첫날, 사용자 10만 명이 몰리자마자 1시간 만에 코어 서버가 타버렸다. 1초면 끝나야 할 계좌 이체가, 분산된 3개의 DB에 Prepare 락을 걸고 대기하느라 5초씩 늘어졌고, 서버의 스레드(Thread) 1만 개가 전부 Lock 반납만 기다리는 웨이팅 상태에 빠져 먹통이 된 것이다.
    • 아키텍트의 해결책: BASE 철학으로의 전면적 개종과 비동기(Async) 이벤트 수용이다. MSA 환경에서 '실시간 무결성(100% ACID)'은 수학적으로 달성 불가능한 신화다. 아키텍트는 즉각 2PC 글로벌 락을 찢어버려야 한다. 결제 서버는 그냥 자기 DB(로컬 트랜잭션)에 "돈 빠짐"만 기록하고 10ms 만에 락을 풀어 스레드를 해방시킨다. 그리고 Kafka 큐에 "돈 뺐으니 타행 송금해!" 메시지를 던지는 **Saga 패턴 (이벤트 주도 아키텍처)**으로 전환해야 한다. "찰나의 1초 동안은 잔고가 짝짝이일지라도, 큐가 돌아가면 결국엔 완벽히 맞춰진다(Eventual Consistency)"라는 타협을 받아들이는 자만이 클라우드의 속도를 누릴 자격이 있다.

도입 체크리스트 (2PC를 그래도 써야 하는 최후의 0.1% 도메인)

  • 비즈니스적: "보상 트랜잭션(환불 로직)을 인간의 상식으로 도저히 짤 수 없는 특수 도메인인가?" 사가 패턴이 대세라지만, 방사능 원자력 발전소 제어 시스템이나 나사(NASA)의 로켓 궤도 수정 트랜잭션에서 "일단 쏘고 나서 궤도 틀리면 보상 트랜잭션 쳐서 수습하자 ㅋ"라고 할 수는 없다. **단 0.001초의 데이터 불일치도 수십만 명의 목숨이나 천문학적 파멸을 부르는 초극단적 도메인(Nuclear, Life-critical)**이라면, 서버 전체가 가동을 멈추고 뻗는 한(가용성 포기)이 있더라도 2PC 락을 걸어 100% 무결성을 챙겨야 한다.
  • 기술적: DB들이 모두 같은 방(동일 리전/초고속 LAN) 안에 있는가? 2PC의 락(Lock) 지연 시간은 물리적 네트워크 거리에 비례해 우주로 뻗어나간다. AWS 서울 리전 DB와 미국 리전 DB를 2PC로 묶으면 핑(Ping) 200ms 동안 전 세계 시스템이 정지하는 헬파티가 열린다. 2PC를 굳이 쓰겠다면 오직 같은 데이터센터 안의 1ms 핑을 보장하는 초고속 내부망(Intranet) 안에서 제한된 2~3개의 관계형 DB(Oracle/MySQL)끼리만 써야 파멸을 면한다.

안티패턴

  • "Kafka 같은 비동기 큐 생태계에 억지 2PC (XA) 들이밀기": 현대 백엔드 개발자가 Kafka 메시지를 쏘는 것과 DB 저장을 2PC 통제기에 물려서 "DB 저장 실패하면 Kafka에 쏜 메시지도 물리적으로 롤백(회수)해 주세요!"라고 우기는 미친 짓. 카프카는 애초에 한 번 뱉은 메시지를 주워 담는(Rollback) 개념 자체가 없는 무한 전진 스트리밍 깡통이다. 분산 스트리밍 환경에서 2PC(XA)를 쑤셔 넣으려 시도하는 순간 개발 3달 하고 결국 불가능함을 깨닫고 다 엎게 된다. 이런 경우엔 반드시 2PC를 버리고 548장에서 설명한 **아웃박스 패턴(Outbox Pattern)**을 적용해 로컬 DB 원자성으로 타협해야 한다.

  • 📢 섹션 요약 비유: 클라우드 시대에 2PC를 고집하는 것은, 전장(네트워크)에서 폭탄이 터지고 총알이 빗발치는데 **'모든 부대원이 동시에 무전기로 <수신 양호> 대답을 해야만 한 발자국을 전진하는 바보 같은 분대장'**과 같습니다. 무전기 고장 난 군인 한 명 때문에 분대 전체가 그 자리에 멈춰 서 있다가 몰살당합니다. 클라우드에선 일단 한 명씩 각개약진(로컬 트랜잭션)으로 존나게 뛰어나간 뒤에, 나중에 목적지(사가 패턴)에서 다친 사람 파악해서 수습(보상)하는 게 유일한 생존법입니다.


Ⅴ. 기대효과 및 결론

정량/정성 기대효과

구분2PC (Two-Phase Commit) 고집 시 (AS-IS)MSA 사상에 맞춘 Saga 패턴 전환 시 (TO-BE)개선 효과
정량트랜잭션 하나당 분산 락(Lock) 점유 시간 3~5초 소요각 서버가 로컬 DB만 건드리고 빠짐 (10ms 컷)응답 지연(Latency) 극감 및 동시 접속 처리량(TPS) 100배 펌핑
정량분산 노드 중 1대라도 타임아웃 나면 전사 트랜잭션 실패죽은 놈 빼고 일단 로컬 커밋 처리, 나중에 비동기 재시도장애 격리(Fault Tolerance)로 전체 가용성(Availability) 99.99% 방어
정성"DB 락 풀릴 때까지 아무것도 못 해 ㅠㅠ 살려줘""일단 사고(저장) 치고, 수습(보상/환불) 로직으로 커버 치자!"클라우드 네이티브의 회복 탄력성(Resilience) 중심 사고 완벽 이식

미래 전망

  • NewSQL의 역습 (글로벌 2PC의 부활?): "야! Saga 패턴 환불 코드 짜는 거 너무 헬이라 다 퇴사하잖아! 그냥 옛날 2PC 편하게 쓸래!" 아키텍트들의 이 피눈물을 먹고 자란 괴물 데이터베이스들이 등장했다. 구글 스패너(Google Spanner)나 코크로치DB(CockroachDB). 이들은 전 세계 지구촌에 분산된 수십 대의 서버를 하나로 묶으면서도, 군사급 GPS 원자 시계(TrueTime)와 합의 알고리즘(Raft)을 하드웨어 바닥에 때려 박아 넣었다. 결국 2PC의 극악의 단점인 느린 속도와 SPOF를 무지막지한 하드웨어 돈지랄로 씹어먹으며, **"MSA로 서버 찢어도 괜찮아. DB는 우리가 알아서 글로벌 락(Lock) 걸어서 옛날 1통짜리 롤백 마술 똑같이 보여줄게"**라는 미친 100% 무결점 2PC의 부활 시대가 열리고 있다. (물론 DB 사용료가 우주로 간다).
  • 분산 트랜잭션 프레임워크의 대중화: 자바(Spring) 생태계에 닥쳐온 변화. 개발자가 일일이 "이거 2PC로 묶어? Saga로 묶어?" 땀 흘리며 짤 필요가 없어진다. 알리바바가 만든 Seata(시타) 같은 초거대 글로벌 분산 트랜잭션 프레임워크가 코드를 먹어 치운다. 어노테이션 @GlobalTransactional 딱 1개만 붙이면, 그 밑바닥에서 알아서 2PC 모드로 돌릴지, Saga/TCC(보상) 모드로 돌릴지 프레임워크 인프라가 알아서 최적화하여 롤백을 때려주는 '무뇌 개발 자동화 인프라' 시대가 안착 중이다.

참고 표준

  • X/Open XA (eXtended Architecture): 1991년 만들어져 은행권의 신으로 군림한, 여러 DB를 하나의 2PC 코디네이터로 묶어주는 전 세계 트랜잭션 동기화의 낡은 대헌장.
  • CAP Theorem (CAP 정리): 2PC를 마이크로서비스에서 쓰면 왜 망하는지를 수학적으로 증명해버린 우주 법칙. "네트워크가 불안정한 상태(P)에서, 2PC로 완벽한 일치(C)를 추구하면 반드시 서버가 뻗는다(가용성 A의 파멸)!"

2PC (Two-Phase Commit)의 맹신과 몰락은, 소프트웨어 공학이 '절대적인 무결성(God's View)'이라는 순진한 환상에서 벗어나, '네트워크는 항상 끊기고 기계는 반드시 부서진다'는 거칠고 현실적인 클라우드의 야생(Wilderness)으로 철학적 진화를 이뤄낸 상징적인 분기점이다. 온프레미스 시대의 따뜻한 전산실 안에서는 2PC의 글로벌 락(Lock)이 가장 우아하고 깨끗한 해답이었다. 단 1줄의 Rollback 코드로 3개의 DB를 원상 복구시키는 마법은 달콤했다. 하지만, 수천만 명의 글로벌 사용자가 접속하고 서버가 1초 단위로 켜졌다 꺼지는 MSA의 거대한 혼돈 속에서, 그 완벽함을 갈구하며 채워놓은 자물쇠(Lock)는 오히려 시스템 전체의 숨통을 조여 죽이는 올가무가 되었다. 아키텍트는 2PC의 달콤한 완벽주의(Perfectionism)를 도끼로 찍어내고, 당장 0.1초 데이터가 틀어지더라도 수습할 수 있는 보상(Compensation)의 맷집을 길러야 한다. 10만 대의 마이크로서비스 우주선 편대는, 한 척이 고장 났다고 전 함대가 멈춰 서서 2PC의 지시를 기다리는 바보가 아니라, 뒤처진 놈은 버려두고 일단 목표를 향해 무한히 전진하며 비동기로 수습하는 압도적 가용성(Availability)의 야수로 진화해야만 살아남을 수 있다.

  • 📢 섹션 요약 비유: 2PC는 **'모든 가족이 한 식탁에 앉아야만 밥을 먹기 시작하는 엄격한 저녁 식사'**입니다. 아버지가 야근으로 3시간 늦으면, 굶주린 나머지 가족 모두가 3시간 동안 밥상 앞에서 침만 흘리다 아사(서버 셧다운)합니다. 현대 클라우드(Saga)는 **'뷔페 식당'**입니다. 그냥 배고픈 놈(로컬 DB)이 먼저 밥을 떠먹습니다(Lock 없음). 아버지가 늦게 와서 맛있는 반찬이 없으면 식당 직원한테 "불고기 더 채워주세요!"라고 사후 보상(보상 트랜잭션)을 요청해서 결국 배를 불리면(Eventual Consistency) 되는 합리적이고 빠른 식사 예절입니다.

📌 관련 개념 맵 (Knowledge Graph)

개념 명칭관계 및 시너지 설명
사가 패턴 (Saga Pattern)2PC가 싼 똥(가용성 파멸)을 치우기 위해 혜성처럼 등장한 클라우드 네이티브 트랜잭션의 구세주. 락(Lock)을 싹 다 박살 내버리고 비동기로 수습하는 미친 속도의 후계자. (다음 장 550번 연계)
마이크로서비스 아키텍처 (MSA)2PC를 멸망시킨 근본적 원인. 모놀리식의 1통짜리 시스템을 수십 개로 갈가리 찢어놓았기 때문에 2PC라는 억지 락(Lock)을 걸면 네트워크 병목으로 다 터져나가게 만든 장본인. (이전 장 532번 연계)
분산 모놀리스 (Distributed Monolith)2PC를 적용한 마이크로서비스 시스템을 부르는 가장 치욕스러운 멸칭. 서버를 50개로 찢어놨는데 2PC 락으로 한 몸처럼 묶여있어, MSA의 장점은 0이고 단점(네트워크 지연)만 100배로 증폭된 쓰레기 구조. (이전 장 537번)
CAP 정리 (CAP Theorem)2PC의 죽음을 논리적으로 선고한 헌법. 파티션 감내(P) 환경에서 2PC가 추구하는 완벽한 정합성(C)을 고집하면 무조건 가용성(A)이 죽는다는 걸 증명했다. (이전 장 531번 클라우드 연계)
보상 트랜잭션 (Compensating TX)2PC의 물리적 롤백(Rollback)을 완전히 대체하는 사가 패턴의 핵심 톱니바퀴. 이미 저장된 돈을 논리적인 환불(-100원 연산) 로직으로 억지로 되돌려버리는 클라우드의 뒷수습술. (이전 장 551번 연계)

👶 어린이를 위한 3줄 비유 설명

  1. 선생님이 우리 반 3명한테 "손 씻고 왔어?"라고 물어보고, 3명 모두가 "네!"라고 똑같이 대답할 때까지 절대 밥을 못 먹게 하는 빡빡한 규칙2PC예요.
  2. 한 친구가 화장실에서 길을 잃어서 대답을 안 하면, 나머지 두 친구는 배가 고파 쓰러지는데도(시스템 셧다운) 10분 내내 밥을 못 먹고 굶으며 기다려야 하는 엄청난 단점이 있죠! (가용성 폭발).
  3. 그래서 요즘 컴퓨터(클라우드)들은 이런 바보 같은 기다림을 버리고, 일단 먼저 손 씻은 친구부터 빨리 밥을 먹게(Saga 패턴) 만들어주는 짱 빠른 방법을 쓴답니다!