OPEN HYPER STEP
← 목록으로 (Java+Spring)
JAVA · 95 / 99
java
CHAPTER 95 / 99
읽기 약 2
FUNCTION

분산 트랜잭션: SAGA 패턴


핵심 개념

2PC의 한계·Choreography vs Orchestration·보상 트랜잭션 — 결제 실패 → 주문 취소.

본문

2PC의 한계

📋 코드 (9줄)
2-Phase Commit:
1. Coordinator → "준비?" → 모든 Participant
2. 모두 OK면 → "커밋!" → 모두 커밋

문제:
- Coordinator 단일 장애점
- Participant 실패 시 락 무한 보유
- 모든 노드 동기 대기 → 느림
- 마이크로서비스에서 거의 사용 안 함

SAGA 패턴

📋 코드 (10줄)
긴 비즈니스 트랜잭션을 여러 로컬 트랜잭션 시퀀스로 분할
각 단계가 실패하면 보상 트랜잭션 (취소 액션) 실행

예: 주문 처리
1. 주문 생성    (보상: 주문 취소)
2. 재고 감소    (보상: 재고 복구)
3. 결제 처리    (보상: 환불)
4. 배송 시작    (보상: 배송 취소)

3단계 실패 → 보상: 2 → 1 순서로 롤백

Choreography (분산형)

📋 코드 (6줄)
각 서비스가 이벤트를 발행하고 다음 서비스가 반응
중앙 조정자 없음

[Order] → OrderCreated → [Inventory] → StockDecremented → [Payment]
                                    ↓ 실패: StockFailedEvent
                                    [Order] → 주문 취소
JAVA📋 코드 (35줄)
// Order Service
@KafkaListener(topics = "stock.failed", groupId = "order")
public void handleStockFailed(StockFailedEvent event) {
    Order order = orderRepo.findById(event.orderId()).orElseThrow();
    order.cancel("재고 부족");
    orderRepo.save(order);

    kafkaTemplate.send("orders.cancelled", event.orderId(),
        new OrderCancelledEvent(event.orderId(), "STOCK_INSUFFICIENT"));
}


// Inventory Service
@KafkaListener(topics = "orders.placed", groupId = "inventory")
public void handleOrderPlaced(OrderPlacedEvent event) {
    try {
        inventory.decrement(event.productId(), event.quantity());
        kafkaTemplate.send("stock.decremented", new StockDecrementedEvent(event));
    } catch (InsufficientStockException e) {
        kafkaTemplate.send("stock.failed", new StockFailedEvent(event.orderId(), e.getMessage()));
    }
}


// Payment Service
@KafkaListener(topics = "stock.decremented", groupId = "payment")
public void handleStockDecremented(StockDecrementedEvent event) {
    try {
        Payment payment = paymentService.charge(event.orderId(), event.amount());
        kafkaTemplate.send("payment.completed", new PaymentCompletedEvent(payment));
    } catch (PaymentException e) {
        // 보상 — 재고 복구 요청
        kafkaTemplate.send("stock.compensate", new StockCompensateEvent(event));
    }
}

Orchestration (중앙 조정형)

📋 코드 (10줄)
중앙 Orchestrator가 모든 단계 조정
명시적 워크플로우

[OrderSaga]
  1. createOrder()
  2. decrementStock()
     실패 → cancelOrder()
  3. processPayment()
     실패 → restoreStock() → cancelOrder()
  4. startShipping()
JAVA📋 코드 (44줄)
@Service
@RequiredArgsConstructor
public class OrderSagaOrchestrator {
    private final OrderClient orderClient;
    private final InventoryClient inventoryClient;
    private final PaymentClient paymentClient;
    private final ShippingClient shippingClient;

    public OrderResult processOrder(OrderRequest req) {
        Order order = null;
        boolean stockDecremented = false;
        boolean paymentCompleted = false;

        try {
            // 1. 주문 생성
            order = orderClient.create(req);

            // 2. 재고 감소
            inventoryClient.decrement(order.getProductId(), order.getQuantity());
            stockDecremented = true;

            // 3. 결제 처리
            Payment payment = paymentClient.charge(order.getId(), order.getTotal());
            paymentCompleted = true;

            // 4. 배송 시작
            shippingClient.start(order.getId());

            return OrderResult.success(order);
        } catch (Exception e) {
            // 보상 — 역순으로 롤백
            if (paymentCompleted) {
                paymentClient.refund(order.getId());
            }
            if (stockDecremented) {
                inventoryClient.restore(order.getProductId(), order.getQuantity());
            }
            if (order != null) {
                orderClient.cancel(order.getId(), e.getMessage());
            }
            return OrderResult.failure(e.getMessage());
        }
    }
}

비교

📋 코드 (14줄)
Choreography:
+ 단순·각 서비스 독립적
+ 중앙 장애점 없음
- 흐름 추적 어려움
- 순환 의존 위험

Orchestration:
+ 흐름 명확 + 디버깅 쉬움
+ 복잡한 분기 가능
- Orchestrator 장애 시 전체 영향
- 중앙 결합도 증가

→ 단순 흐름은 Choreography
→ 복잡 흐름은 Orchestration (Camunda, Temporal)

다음 챕터

CH.27 "K8s 기초" — 컨테이너 오케스트레이션.


AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude

무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6

내 Spring 코드의 SAGA 패턴 부분을 분석해서
보상 트랜잭션 신뢰성와 개선 우선순위를 알려줘.
ChatGPT

무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro

SAGA 패턴 vs 다른 패턴 비교를
실전 사례 5개로 보여주고 Choreography vs Orchestration를 알려줘.
Gemini

무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro

내 코드베이스 전체를 분석해서
SAGA 패턴 관련 eventually consistent 위험 위치를 보고해줘.
Grok

무료: Grok 4.1 / SuperGrok $30/mo

2026년 한국 기업의 SAGA 패턴 채택률과
한국 이커머스 분산 트랜잭션를 솔직히 알려줘.

⭐ 이것만 기억하세요
분산 트랜잭션: SAGA 패턴 이 3가지만 확실히 잡으세요
1.2PC는 분산 시스템에 부적합 — SAGA로 보상 트랜잭션 패턴
2.Choreography는 이벤트 기반 분산형, Orchestration은 명시적 중앙 조정
3.다음 챕터 CH.27에서 K8s — 컨테이너 오케스트레이션


공유하기
진행도 95 / 99