Book trip: (1) giữ phòng (2) charge thẻ (3) gửi voucher. Bước 2 fail sau khi (1) ok — không có transaction phân tán magic rollback cả hotel lẫn bank.
Saga: chuỗi bước local; nếu fail → chạy compensation cho bước đã thành công (hủy phòng, refund) — reverse nghiệp vụ, không phải DELETE hàng DB toàn cục.
Ví dụ fail ở bước 2
1 reserve_room(order) OK
2 charge_card(order) FAIL (insufficient / timeout uncertain)
3 issue_voucher — không chạy
Compensate:
1' cancel_reservation(order) // idempotent
2' nếu charge uncertain → tra cứu / không charge lại mù
(stale-missing-wrong · uncertain, retry-what-when)
Orchestration vs choreography
- Orchestration: một coordinator (state machine) gọi từng bước, quyết compensate. Dễ audit, single point logic.
- Choreography: event “RoomReserved” → service charge tự nghe. Lỏng coupling, khó theo dõi “saga đang đâu”, dễ mất event nếu dual-write.
Quy tắc sống còn
- Mỗi bước + mỗi compensate idempotent (redelivery, retry).
- State saga (bước hiện tại) bền — crash giữa chừng resume được.
- Publish chuyển bước: outbox, không dual-write.
- Compensate cũng fail → DLQ / manual, không pretend atomic.
- Timeout bước: uncertain — đừng compensate + retry create cùng lúc mù.
Khi không cần saga đầy đủ
Một DB + một transaction local đủ; hoặc bước sau best-effort (email) với ignore có SLA — đừng over-engineer.
Một câu
Saga chấp nhận tạm sai để tiến — bù trừ có chủ đích, không ảo
2PC.
Idempotent từng bước; outbox; uncertain xử lý trước khi
compensate.