Saga는 성공한 로컬 커밋만 역순 보상한다
여러 서비스가 하나의 ACID 트랜잭션으로 묶이지 않을 때, 각 단계는 자기 DB에 먼저 커밋한다. 중간 실패가 나면 DB 롤백이 아니라 이미 성공한 업무를 반대 의미의 새 명령으로 되돌린다.
결제 실패 후 보상 스택이 만들어지는 순간
예: 주문 생성과 재고 예약은 이미 커밋됐고, 결제 승인에서 영구 실패가 난 상황이다.
로컬 트랜잭션
Order DB에 PENDING_ORDER와 orderId를 저장한다.
Inventory DB에 reservationId와 예약 수량을 남긴다.
영구 실패면 다음 성공 단계로 가지 않고 보상으로 전환한다.
보상 트랜잭션
reservationId 기준으로 재고 예약을 한 번만 해제한다.
orderId 상태를 CANCELLED로 전이하고 취소 이벤트를 남긴다.
보상 완료, 실패, 재시도 대기 상태를 대시보드에 노출한다.
재고 예약 해제, 주문 취소처럼 도메인 의미가 반대인 명령을 별도로 구현한다.
commandId와 처리 이력으로 중복 이벤트와 오케스트레이터 재시작을 견딘다.
PROCESSING, COMPENSATING, FAILED처럼 원자적 커밋 사이의 상태를 명확히 표시한다.