분산 트랜잭션의 2단계 커밋: 준비·결정·블로킹
2PC의 준비와 전역 결정, 조정자 장애 때 참여자가 기다리는 이유, 장기 prepared 상태의 운영 위험을 설명합니다.
발행·오류 제보: infostoa · 편집 기준
이 글의 개별 작성자와 전문 검토자 정보는 제공되지 않습니다.
여러 데이터베이스에 걸친 한 업무에서 일부만 반영되면 주문과 결제가 서로 다른 상태가 될 수 있습니다. 2단계 커밋(2PC)은 참여자가 먼저 커밋 준비를 약속하게 한 다음 조정자가 전역 결정을 전달하는 프로토콜입니다. 원자성을 돕지만, 조정자와 참여자의 복구 상태를 관리해야 하고 장애 중 작업이 대기할 수 있습니다.
원자적 커밋이 필요한 상황
분산 트랜잭션은 독립된 자원에 걸친 변경을 하나의 업무처럼 맞추려는 상황에서 등장합니다. 예컨대 서로 다른 저장소가 하나의 주문에 필요한 변경을 처리할 때, 한쪽만 확정되면 데이터 정합성을 복구하기 어려울 수 있습니다. 2PC는 참여자 모두가 동의한 경우에만 전체 커밋을 진행하고, 준비가 불가능한 참여자가 있으면 취소 결정을 내리는 방식으로 전부 반영 또는 전부 취소라는 목표를 지원합니다.
준비 단계에서 참여자가 보장하는 것
조정자는 각 참여자에게 변경을 커밋할 수 있는지 묻습니다. 참여자는 필요한 변경을 준비된 상태로 기록하고, 복구 뒤에도 결정을 이어갈 수 있게 로그를 남긴 다음 준비 완료 또는 거부를 응답합니다. Martin Fowler의 패턴 설명은 필요한 잠금 같은 자원을 준비 단계에서 확보한다고 설명합니다. 이 시점의 “예”는 이미 최종 커밋했다는 뜻이 아니라, 결정이 전달되면 커밋하겠다는 약속입니다.
전역 커밋과 중단 결정
모든 참여자가 준비에 동의하면 조정자가 커밋 결정을 보내고 각 참여자는 변경을 확정합니다. 하나라도 준비할 수 없다고 답하면 조정자는 롤백 결정을 알립니다. PostgreSQL에서는 PREPARE TRANSACTION 뒤 COMMIT PREPARED 또는 ROLLBACK PREPARED가 해당 자원 상태를 해결하는 명령입니다. 이는 PostgreSQL의 외부 트랜잭션 관리자 지원 방식이며 SQL 일반 기능 전체를 대표하지 않습니다.
조정자 장애와 블로킹의 정확한 의미
참여자가 준비 완료를 기록한 뒤 조정자가 사라지면 참여자는 전역 결정이 커밋인지 중단인지 알 수 없어 준비 상태와 잠금을 유지할 수 있습니다. 이는 데이터 일관성을 함부로 깨지 않으려는 대가로 진전을 기다리는 블로킹 문제입니다. 영구적인 교착이 항상 발생한다는 뜻은 아닙니다. 조정자의 내구성 있는 로그, 복구 절차, 재시작 뒤 재전달로 결정을 회복할 수 있지만, 의사결정자와 네트워크가 모두 불확실하면 참여자만으로 안전하게 새 결정을 만들 수 없습니다.
전문가 관점: 자원 점유와 복구 운영을 설계한다
PostgreSQL은 prepared 상태를 오래 열어 두면 잠금을 계속 보유하고 VACUUM의 저장공간 회수를 방해하며, 극단적으로 트랜잭션 ID wraparound 위험을 막으려 서버가 중단될 수 있다고 경고합니다. 운영자는 미해결 트랜잭션을 추적하고 외부 트랜잭션 관리자가 빠르게 마무리하도록 설계해야 합니다.
PostgreSQL의 pg_prepared_xacts 뷰는 현재 준비 상태에 남아 있는 트랜잭션을 보여 줍니다. 운영 점검은 이 관측값을 외부 관리자의 기록과 대조해 누락되거나 장기간 열린 작업을 찾는 데 활용할 수 있습니다. 이미 커밋한 다른 서비스에 대한 보상 작업이 필요한 업무는 Saga가 대안일 수 있지만, 보상은 원자적 롤백과 같지 않으므로 비즈니스 의미를 따로 다뤄야 합니다.
구현을 검토할 때 확인할 점
참여자별 준비 로그가 장애 후 복구되는지, 조정자 결정을 중복 전달해도 결과가 안전한지, 미해결 상태에 시간 제한·경보·운영 복구 절차가 있는지 점검하세요. PostgreSQL을 쓴다면 prepared transaction 기능을 외부 관리자가 추적하는 경우에만 활성화하라는 문서 주의를 따르십시오. 처리량과 가용성의 선택은 업무의 일관성 요구와 자원별 기능에 따라 다릅니다.
복구 때는 참여자별 영속 로그와 조정자의 결정 로그를 대조해 준비·커밋·중단 상태를 확인하고, 상태를 추정으로 정하지 마세요. PostgreSQL의 pg_prepared_xacts를 외부 관리자의 기록과 대조하면 누락되거나 오래 열린 작업을 찾는 데 도움이 됩니다. 재전달된 결정을 자원별로 안전하게 처리하는지도 확인하세요.
출처
- PostgreSQL 16, PREPARE TRANSACTION — prepared 상태, 해결 명령, 외부 트랜잭션 관리자, 장기 미해결 상태의 주의점. PostgreSQL 구현 문서입니다.
- Unmesh Joshi, Two-Phase Commit (2023) — prepare/commit 투표와 참여자의 내구성 있는 복구 약속을 설명하는 분산 시스템 패턴 자료.