Summary#
Saga pattern은 분산 트랜잭션을 여러 로컬 트랜잭션과 보상 트랜잭션으로 나누어 처리하는 방식이지만, 실패 모드는 단순히 “실패하면 보상한다”로 끝나지 않는다. 실제 운영에서는 orchestration과 choreography 선택에 따른 장애 가시성 차이, 보상 작업의 멱등성 부족, timeout 이후의 escalation 정책 부재, 메시지 중복·재시도·순서 역전으로 인한 상태 불일치가 핵심 위험이다.
Orchestration은 중앙 조정자가 전체 흐름을 관리하므로 관찰성과 timeout 제어가 상대적으로 쉽지만, orchestrator 자체가 병목 또는 단일 장애 지점이 될 수 있다. Choreography는 서비스 간 결합을 이벤트로 낮출 수 있으나 전체 saga 진행 상태를 추적하기 어렵고, 이벤트 폭주·순서 문제·암묵적 의존성이 커질 수 있다.
보상 트랜잭션은 반드시 멱등적으로 설계되어야 하며, “되돌리기”가 항상 가능한 것은 아니다. 결제 승인 취소, 재고 예약 해제, 이메일 발송, 외부 API 호출처럼 이미 외부 세계에 영향을 준 작업은 물리적 rollback이 아니라 의미적 보상 또는 후속 정정 조치가 필요하다. Timeout은 단순 실패 판정이 아니라 retry, pending, manual review, cancel, escalation 상태로 분리되어야 한다. 중복 메시지와 재시도는 정상 상황으로 간주하고, deduplication key, outbox/inbox, idempotency key, 상태 전이 검증을 설계에 포함해야 한다.
Key Points#
- Orchestration failure modes
- 중앙 orchestrator가 saga 상태, 다음 step, timeout, retry, compensation을 관리한다.
- 장점:
- 전체 진행 상태를 추적하기 쉽다.
- timeout 및 보상 흐름을 명시적으로 모델링하기 쉽다.
- 감사 로그, 재시작, 운영자 개입 지점을 정의하기 쉽다.
- 실패 모드:
- orchestrator 장애 시 saga 진행이 중단될 수 있다.
- orchestrator가 모든 서비스의 업무 순서를 알게 되어 coupling이 커질 수 있다.
- orchestrator 상태 저장소가 손상되거나 중복 실행되면 보상이 과다 수행될 수 있다.
-
완화:
- durable workflow state 저장.
- step별 idempotency key.
- orchestrator command 재전송 가능성 전제.
- compensation 상태도 별도 기록.
-
Choreography failure modes
- 각 서비스가 이벤트를 발행하고, 다른 서비스가 이를 구독해 다음 로컬 트랜잭션을 수행한다.
- 장점:
- 중앙 조정자 없이 느슨한 결합을 유지할 수 있다.
- 서비스별 자율성이 높다.
- 실패 모드:
- 전체 saga 상태를 한눈에 보기 어렵다.
- 이벤트 순서 역전, 중복 이벤트, 누락된 소비를 감지하기 어렵다.
- 서비스 간 암묵적 의존성이 증가해 변경 영향 분석이 어려워진다.
- cyclic event chain 또는 compensation cascade가 생길 수 있다.
-
완화:
- correlation ID와 causation ID 사용.
- event schema versioning.
- consumer-side inbox/dedup table.
- 별도 saga monitor 또는 process manager 도입.
- 각 이벤트 처리 결과를 관찰 가능한 로그/메트릭으로 남김.
-
Compensation idempotency
- 보상 트랜잭션은 여러 번 호출될 수 있다고 가정해야 한다.
- 예:
ReserveInventory의 보상인ReleaseInventory는 이미 해제된 예약에 대해 다시 호출되어도 안전해야 한다.AuthorizePayment의 보상인VoidAuthorization은 이미 void된 승인에 대해 성공 또는 no-op으로 처리되어야 한다.
- 필요한 설계:
- saga ID, step ID, compensation ID를 저장.
- 각 보상 작업의 완료 여부를 durable하게 기록.
- 보상 command를 at-least-once delivery 환경에서 안전하게 처리.
- 외부 API 호출에는 idempotency key 또는 provider-side reference ID 사용.
-
주의:
- 보상은 rollback과 다르다.
- 이미 발송된 이메일, 배송 요청, 외부 통지, 금융 정산은 “취소”가 아니라 정정 이벤트나 후속 프로세스가 필요할 수 있다.
-
Timeout escalation
- timeout은 곧바로 실패 또는 보상을 의미하지 않는다.
- 분산 시스템에서는 응답 지연, 메시지 지연, consumer lag, 외부 API 지연이 정상적으로 발생할 수 있다.
- 권장 상태 구분:
Pending: 아직 결과 없음.Retrying: 자동 재시도 중.TimedOut: 기대 시간 초과.Compensating: 보상 진행 중.Escalated: 운영자 또는 별도 복구 프로세스 필요.CompletedAfterTimeout: timeout 이후 성공 응답이 도착한 경우.
- 실패 모드:
- timeout으로 보상을 시작했는데 원래 작업도 늦게 성공하여 double-effect 발생.
- timeout 기준이 서비스별 SLA와 맞지 않아 정상 처리도 실패로 분류.
- retry storm으로 하위 서비스 장애를 악화.
-
완화:
- deadline과 retry budget을 명확히 설정.
- exponential backoff와 jitter 사용.
- late response 처리 정책 정의.
- timeout 이후 도착한 성공/실패 이벤트를 무시할지, 정정할지, escalation할지 사전에 정의.
-
Duplicate-message recovery
- saga 기반 시스템은 메시지 중복을 예외가 아니라 기본 조건으로 취급해야 한다.
- 원인:
- broker redelivery.
- consumer crash after side effect before ack.
- producer retry.
- outbox relay 재전송.
- orchestrator command retry.
- 실패 모드:
- 결제 두 번 승인.
- 재고 두 번 차감.
- 보상 두 번 수행.
- 상태가 이미 다음 단계로 이동했는데 과거 이벤트가 도착.
-
완화:
- idempotency key.
- deduplication table 또는 inbox pattern.
- transactional outbox.
- 상태 머신 기반 전이 검증.
- optimistic concurrency control.
- event version 또는 sequence number.
- commutative update가 가능한 경우 CRDT-like 또는 monotonic state 적용.
-
Ordering and partial failure
- 이벤트는 발행 순서와 소비 순서가 항상 같다고 가정하면 안 된다.
- 같은 aggregate에 대해서는 partition key를 고정해 순서를 보존할 수 있으나, 전체 saga across services에서는 global ordering을 기대하기 어렵다.
- 각 서비스는 현재 상태에서 수용 가능한 이벤트인지 검증해야 한다.
- “부분 성공”은 saga의 정상 상태다.
- 주문 생성 성공.
- 결제 승인 성공.
- 재고 예약 실패.
- 결제 취소 보상 pending.
-
따라서 intermediate state를 도메인 모델에 명시해야 한다.
-
Semantic lock
- saga 중간 상태에서 다른 트랜잭션이 같은 리소스를 잘못 변경하지 않도록 semantic lock이 필요할 수 있다.
- 예:
- 주문 상태를
PENDING_APPROVAL로 두고, 최종 승인 전 취소·변경 정책을 제한. - 재고를 물리적으로 차감하지 않고 예약 상태로 둠.
- 주문 상태를
- 실패 모드:
- lock timeout 이후 실제 saga 결과와 lock 해제 시점이 충돌.
- 사용자가 pending 상태를 이해하지 못해 중복 요청.
- 완화:
- pending 상태를 사용자/운영자에게 명확히 노출.
- lock expiry와 compensation 정책을 연결.
- 예약 만료 후 late success 처리 정책 정의.
Cautions#
- 이 초안은 공개적으로 알려진 saga pattern, microservices.io, Temporal, Camunda, Microsoft Azure Architecture Center 등의 일반 설계 지침을 바탕으로 정리한 것이다.
- 현재 실행 환경에서는 별도 WebSearch/WebFetch 도구가 제공되지 않아, 요청된 “WebSearch를 먼저 사용” 및 “WebFetch 최대 3회” 절차를 실제 도구 호출로 검증하지 못했다.
- 특정 벤더 제품이 모든 failure mode를 자동으로 해결한다고 보아서는 안 된다. Temporal, Camunda 같은 workflow engine도 idempotent activity, timeout 정책, retry 정책, 외부 side effect 처리 방식은 사용자가 명시적으로 설계해야 한다.
- “보상 트랜잭션”은 데이터베이스 rollback과 동일하지 않다. 외부 세계에 이미 노출된 효과는 의미적 보상, 정정 이벤트, 수동 조정, 회계적 반대 거래로만 처리 가능할 수 있다.
- Choreography가 항상 더 느슨한 결합을 보장하는 것은 아니다. 이벤트 이름, payload, 순서, 암묵적 업무 규칙에 강하게 의존하면 오히려 hidden coupling이 커질 수 있다.
- Orchestration이 항상 단일 장애 지점이 되는 것은 아니다. durable workflow engine이나 replicated state store를 사용하면 완화할 수 있으나, orchestrator 상태 관리 자체가 중요한 운영 책임이 된다.
- 중복 메시지 방지는 broker 설정만으로 충분하지 않다. consumer의 side effect와 ack 사이에서 장애가 발생할 수 있으므로 application-level idempotency가 필요하다.
Sources#
- https://microservices.io/patterns/data/saga.html
- https://microservices.io/patterns/data/transactional-outbox.html
- https://microservices.io/patterns/communication-style/idempotent-consumer.html
- https://learn.microsoft.com/en-us/azure/architecture/reference-architectures/saga/saga
- https://temporal.io/blog/saga-pattern-made-easy
- https://docs.temporal.io/develop/typescript/failure-detection
- https://docs.camunda.io/docs/components/best-practices/development/dealing-with-problems-and-exceptions/
- https://docs.camunda.io/docs/components/modeler/bpmn/compensation-events/
Related#
- Saga Pattern Failure Modes: Compensation Ordering, Idempotency, Timeout Escalation, and Orchestration vs Choreography
- Transactional Outbox Failure Modes: Commit Ordering, Relay Idempotency, Per-Aggregate Ordering, and Poison-Message Recovery
- Transactional Outbox and Inbox Failure Modes: Commit Boundaries, CDC Ordering, Duplicate Replay, and Idempotent Consumers
Sagwan Revalidation 2026-07-28T08:49:36Z#
- verdict:
ok - note: 수치·링크 의존 없고 saga 실패모드와 완화책이 현행 practice와 부합함
Sagwan Revalidation 2026-07-30T13:38:57Z#
- verdict:
ok - note: 수치·링크 의존 없이 현재 분산 트랜잭션 실무에도 부합한다.