Skip to content
사고 기록
뒤로

분산 트랜잭션

Table of contents

Open Table of contents

분산 트랜잭션

여러 독립된 노드(DB or Service)의 데이터 조작을 원자적으로 처리하여 데이터 일관성을 유지하는 기법을 말한다.

MSA나 분산 DB 환경에서는 단일 DB의 ACID 보장이 불가능하므로 CAP 정리와 BASE 이론을 바탕으로 설계 방식을 결정해야 한다.

핵심 기본 개념

  • CAP 정리
    • 일관성(Consistency), 가용성(Availability), 분할 허용성(Partition Tolerance) 이 3가지를 분산환경에서 동시에 100% 만족할 수 없음
    • 네트워크 단절은 분산 환경에서 피할 수 없으므로 실제 설계는 CP(가용성을 포기하고 데이터 일치 우선) 또는 AP(데이터 불일치를 감수하고 무조건 응답 우선) 중 하나를 선택
  • BASE 모델
    • 즉각적인 일관성(ACID) 대신 기본적 가용성(Basically Available), 유연한 상태(Soft state), 최종 일관성(Eventual Consistency)을 목표로 함
    • BA (Basically Available, 기본적 가용성)
      • 전체 시스템이 죽지 않고, 일부 장애가 발생해도 서비스는 계속 작동
      • 결제 트래픽 폭주 시 대기열 페이지를 띄우거나, 일부 추천 기능만 비활성화하고 핵심 주문은 처리
    • S (Soft State, 유연한/임시 상태)
      • 사용자 입력이 없어도 노드 간 데이터 동기화 과정에서 데이터 상태가 시간에 따라 변할 수 있음
      • 주문 완료 직후 배송 상태가 ‘처리 중’에서 1~2초 뒤 ‘준비 완료’로 백그라운드에서 전환
    • E (Eventual Consistency, 최종 일관성)
      • 실시간으로는 노드 간 데이터가 잠깐 다를 수 있지만, 시간이 지나면 결국 모든 노드의 데이터가 일치하게 됩니다.
      • SNS에서 ‘좋아요’를 눌렀을 때, 친구 화면에는 1~2초 뒤에 반영되지만 결국 같은 숫자로 맞춰짐

구현 방식

2PC(Two-Phase Commit)

여러 서비스에 걸친 분산 트랜잭션에서 모든 노드가 전부 커밋되거나 전부 롤백되도록 보장

  • 1단계(Prepare) → 모든 노드의 준비 상태를 확인
  • 2단계(Commit/Rollback) → 전체 반영 여부를 결정
  • 강한 일관성을 보장하지만 장애 시 단일 장애점(SPOF)이 되고 락 점유로 인해 응답 지연 및 처리량 저하가 발생

Saga 패턴 (보상 트랜잭션)

  • 전체 작업을 로컬 트랜잭션의 연속으로 쪼개어 순차 실행하고 중간 실패 시 이전에 성공한 작업을 되돌리는 보상 트랜잭션을 실행

  • 구현 방식

    • Choreography: 중앙 제어자 없이 각 서비스가 이벤트를 발행(Publish)하고 구독(Subscribe)하며 연속적으로 처리

      정상 성공 흐름
      	1.	주문 서비스: 주문 생성(PENDING) → 주문 생성됨 이벤트 발행
      	2.	결제 서비스: 이벤트 수신 후 결제 처리 → 결제 완료됨 이벤트 발행
      	3.	재고 서비스: 이벤트 수신 후 재고 차감 → 재고 차감됨 이벤트 발행
      	4.	주문 서비스: 재고 완료 이벤트 수신 후 주문 상태를 완료(CONFIRMED)로 최종 갱신
      
      실패 및 보상 트랜잭션 흐름 (재고 부족 실패 예시)
      	1.	주문 서비스: 주문 생성 → 주문 생성됨 이벤트 발행
      	2.	결제 서비스: 결제 처리 성공 → 결제 완료됨 이벤트 발행
      	3.	재고 서비스: 재고 부족으로 처리 실패 → 재고 차감 실패 이벤트 발행
      	4.	결제 서비스: 실패 이벤트 수신 → 결제 취소(환불) 보상 트랜잭션 실행
      	5.	주문 서비스: 실패 이벤트 수신 → 주문 상태를 **주문 취소(CANCELLED)**로 갱신
    • Orchestration: 중앙 오케스트레이터가 순서를 관리하며 각 서비스에 커맨드를 전달

      • OpenFeign + Resilience4j + Eureka (Spring Cloud 컴포넌트, 동기 호출 기반)
      [Saga 오케스트레이터]
      
             ├─ 1. 결제 요청 ──> [결제 서비스] (성공)
      
             ├─ 2. 재고 차감 요청 ──> [재고 서비스] (❌ 실패 반환: 재고 부족)
      
             ├─ 3. 결제 취소 명령(보상) ──> [결제 서비스] (환불 처리 완료)
      
             └─ 4. 주문 실패 처리 ──> [주문 서비스] (주문 상태 CANCELLED 갱신)
      
  • 성능과 가용성이 높고 최종 일관성을 지원하지만 롤백 로직 구현이 복잡하고 격리성이 보장되지 않아 더티 리드(Dirty Read) 대응 설계가 필요

Transactional Outbox 패턴

  • DB 트랜잭션 내에서 비즈니스 데이터와 함께 아웃박스(Outbox) 테이블에 이벤트를 함께 저장한 뒤, 별도 프로세스(Debezium, Polling 등)가 메시지 브로커로 안정적으로 발행
  • DB 변경과 메시지 발행 사이의 원자성을 보장하여 메시지 유실 및 불일치 문제를 해결

설계 시 핵심 고려사항

  • 멱등성 보장
    • 분산 환경의 네트워크 재시도로 인해 메시지가 중복 전달될 수 있으므로, 고유 ID(RequestId, TransactionId)를 기반으로 중복 처리를 방지해야 함
  • 격리성 부재 해결
    • Saga 패턴 적용 시 중간 상태 노출을 방지하기 위해 시맨틱 락, 비관적 업데이트 등의 방어 로직 적용
  • 모니터링 및 복구
    • 보상 트랜잭션마저 실패하는 엣지 케이스를 대비해 데드 레터 큐(DLQ) 적재 및 관리자 수동 개입/재시도 파이프라인 구축