- vừa được xem lúc

Saga Pattern: Khi Lý Thuyết Va Chạm Thực Tế

0 0 2

Người đăng: lowkey dev

Theo Viblo Asia

Bạn mở máy, mở IDE, chuẩn bị triển khai flow đặt hàng trong microservices. Trong đầu, bạn vẫn còn hình dung những gì đã đọc về Saga Pattern:

“Ồ, dễ thôi. Mỗi service tự xử lý transaction, lỗi thì rollback bằng compensate. Eventual consistency? Chuyện nhỏ, Saga lo hết.”

Nghe thì hay, nghe thì gọn gàng… nhưng khi code thực tế, bạn mới nhận ra mọi thứ không hề trơn tru.

Bạn tưởng tượng flow lý tưởng trong đầu:

  1. Order Service tạo đơn.
  2. Payment Service trừ tiền.
  3. Inventory Service giảm stock.
  4. Shipping Service tạo shipment.

Trong sách, nếu bước nào fail → compensate → mọi thứ trở về trạng thái ban đầu, hệ thống hoàn hảo. Trong đầu bạn, đó là một vũ điệu trơn tru.

Nhưng thực tế… là một vũ điệu khác hẳn. Một cú network timeout, một duplicate event hay một compensate không hoàn hảo, và vũ điệu ấy nhanh chóng trở thành… cơn ác mộng vận hành.

image.png


1. Partial Failure – Cú Sốc Đầu Tiên

Bạn tưởng tượng: Payment Service trừ tiền thành công, nhưng Order Service chưa nhận event vì network timeout.

Kết quả? Khách hàng mất tiền, đơn hàng chưa tạo. Bạn thử retry, nhưng mọi thứ tệ hơn: duplicate event → tiền bị trừ hai lần, stock giảm nhầm, shipment đôi.

Partial failure và duplicate event không phải ngoại lệ, mà là thực tế microservices.

Bạn nhận ra: nếu partial failure đã phức tạp, thì rollback và compensate liệu có cứu được tình hình?


2. Compensate – Khi Rollback Không Bao Giờ Hoàn Hảo

Sách vở dạy: rollback chỉ cần gọi function compensate → mọi thứ về trạng thái ban đầu.

Thực tế:

  • Email đã gửi → không undo được.
  • Shipment label đã tạo → không thể hoàn tác.
  • Booking bên thứ ba → rollback gần như bất khả.

Ví dụ: một service gửi SMS xác nhận thanh toán. Nếu transaction fail, bạn không thể “thu hồi” SMS đã gửi. Compensate chỉ bù đắp bằng hành động khác, như gửi thông báo hủy hoặc tạo credit.

Saga không phải phép màu. Compensate chỉ gần đúng, đôi khi phải nhờ manual intervention.

Nhưng câu chuyện chưa dừng ở đây. Nếu trạng thái chưa đồng bộ, khách hàng sẽ thấy gì? Đây là lúc bạn phải nghĩ đến Eventual Consistency.


3. Eventual Consistency – Trade-Off Không Thể Tránh

Dữ liệu cuối cùng sẽ đồng bộ, nhưng khách hàng có thể thấy: “Đang xử lý”, nhưng tiền đã trừ, đơn chưa tạo.

Bạn nhận ra:

  • UX phải che giấu trạng thái tạm thời.
  • Hệ thống cần giám sát, retry, reconcile.
  • Alert phải rõ ràng.

Eventual consistency không miễn phí. Nó yêu cầu bạn chấp nhận rủi ro tạm thời. Nếu không, bạn sẽ nhận hàng loạt support ticket từ khách hàng.

Khi bạn đang tính toán UX, câu hỏi lóe lên: nên quản lý flow bằng một “đạo diễn trung tâm” hay để các service tự xử lý? Đây chính là lúc Orchestration và Choreography xuất hiện.


4. Orchestration hay Choreography – Lựa Chọn Đau Đầu

Bạn phải chọn:

Tiêu chí Orchestration Choreography
Debug & Monitoring Dễ track trạng thái Saga Khó debug, cần logging chi tiết
Single Point of Failure Có orchestrator Không SPoF, phân tán
Duplicate Event Dễ kiểm soát Dễ xảy ra, cần idempotency & retry queue
Flexibility Flow chuẩn, ít linh hoạt Linh hoạt khi add/remove service
Deployment & Scaling Orchestrator cần scale đặc biệt Dễ scale từng service

Một ví dụ: bạn muốn thêm service gửi voucher khuyến mãi sau khi đơn hàng hoàn tất.

  • Orchestration: update orchestrator flow, dễ kiểm soát.
  • Choreography: thêm listener cho event, nhưng phải đảm bảo idempotency và retry queue, dễ lỗi nếu event trễ hoặc duplicate.

Bạn nhận ra: không có lựa chọn hoàn hảo. Debug dễ hay tránh SPoF? Chấp nhận inconsistent tạm thời hay strict consistency? Saga không chỉ là kỹ thuật – là trade-off liên tục.

Và khi bạn cân nhắc, cảnh báo đỏ xuất hiện: không phải lúc nào Saga cũng cứu được tình thế, đặc biệt với các hệ thống yêu cầu strong consistency.


5. Saga Không Phải Giải Pháp Cho Mọi Bài Toán

Hãy tưởng tượng: ngân hàng, chuyển tiền giữa hai tài khoản. Bạn quyết định dùng Saga: trừ tiền từ A, cộng tiền vào B, ghi log giao dịch.

Ban đầu bạn tự tin: bước nào fail → compensate → mọi thứ ổn.

Rồi thảm họa xảy ra. Payment Service đã trừ tiền, nhưng Ledger Service chưa nhận event. Khách hàng hoảng, support team bận rộn. Compensate? Không cứu nổi. Chỉ còn manual intervention.

Lúc này, bạn mới hiểu: Saga không phù hợp với giao dịch ngân hàng. Một giải pháp an toàn hơn: 2-Phase Commit (2PC).

  • 2PC đảm bảo strong consistency: commit đồng bộ, fail → rollback ngay.
  • Tránh partial failure nguy hiểm: khách hàng không thấy số dư tạm thời sai lệch.
  • Integrity tuyệt đối: giao dịch quan trọng luôn chính xác.

Bài học: chọn công cụ sai, microservices có thể biến thành cơn ác mộng vận hành, dù bạn chỉ muốn “áp dụng kỹ thuật cho đẹp mắt”.


6. Bài Học Thực Tế Khi Áp Dụng Saga

Sau tất cả cú sốc từ partial failure, compensate gần đúng, duplicate event và lựa chọn mô hình, bạn bắt đầu rút ra những bài học “thấm thía”.

Bạn nhớ lại lần đầu deploy Saga: event bị trễ, compensate gọi sai thứ tự, khách hàng gọi support liên tục. Khi đó, bạn mới hiểu:

  • Retry không kiểm soát = thảm họa. Idempotency là bắt buộc.
  • Compensate không cứu tất cả. Nó chỉ giảm rủi ro, đôi khi bạn vẫn cần can thiệp tay.
  • Khách hàng nhìn thấy trạng thái tạm thời chưa đồng bộ? UX phải khéo, alert phải rõ ràng, reconcile luôn sẵn sàng.
  • Mô hình triển khai không có lựa chọn hoàn hảo. Orchestration dễ debug nhưng SPoF; Choreography phân tán nhưng khó trace. Chọn flow phù hợp, không phải chọn theo cảm hứng.
  • Saga không dành cho mọi hệ thống. Nếu nghiệp vụ đòi hỏi strong consistency – ví dụ ngân hàng – 2PC hay transaction đồng bộ vẫn là lựa chọn an toàn hơn.

Nhìn lại, bạn nhận ra: Saga không phải phép màu, mà là công cụ tinh tế. Áp dụng đúng chỗ → giảm rủi ro, linh hoạt. Áp dụng sai → cơn ác mộng vận hành.

Điều quan trọng nhất: đừng áp dụng vì nó “ngầu”, hãy áp dụng vì nó thực sự phù hợp với nghiệp vụ của bạn.


Kết Luận

Saga Pattern là công cụ tuyệt vời cho distributed transaction phức tạp, nhưng không phải giải pháp cho mọi bài toán.

Điểm cần nhớ:

  • Hiểu trade-off và edge case.
  • Chuẩn bị monitoring, alert, retry, reconcile, và cả manual intervention.
  • Lựa chọn giữa Orchestration và Choreography dựa trên flow, debug, SPoF.
  • Đánh giá đặc thù hệ thống trước khi triển khai Saga, tránh môi trường đòi hỏi strong consistency, nơi 2PC hoặc transaction đồng bộ khác sẽ phù hợp hơn.

Sau khi đọc xong, bạn sẽ tự hỏi:

“Liệu nghiệp vụ này có thực sự cần Saga, hay tôi chỉ tạo thêm phức tạp cho bản thân?”

Hiểu rõ điều này, bạn sẽ triển khai Saga an toàn, linh hoạt, hiệu quả, thay vì bị cuốn vào cơn ác mộng vận hành hoàn toàn có thể tránh được.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Một Vài điều suy nghĩ về API GateWay

Trong bất kì một hệ thống sử dụng mô hình microservice nào đều có 1 cánh cổng thần kì =)). Đó là API GATEWAY.

0 0 59

- vừa được xem lúc

Microservice 001: Monolithic và sự hình thành của Microservice

Bài viết nằm trong series Microservice: What, when and how. Thời còn sinh viên, chúng ta đã quen thuộc với việc phát triển sản phẩm với mô hình Monolithic, nói nôm na là toàn bộ code được đóng gói và

0 0 97

- vừa được xem lúc

Keycloak Secure any application

In life, there are many problems posed to the software industry . But most of the software that we create has a security and decentralization mechanism and user management.

0 0 58

- vừa được xem lúc

Tìm hiểu về Service Mesh (phần tiếp theo)

Sau bài viết trước Tìm hiểu về Service Mesh là những khái niệm tổng quan về Service Mesh, Istio. Trong bài viết này, chúng ta sẽ tiếp tục tìm hiểu về Istio và thử triển khai Istio lên nhé .

0 0 221

- vừa được xem lúc

Viết ứng dụng Microservice với Golang

Cách xây dựng ứng dụng Microservice với Golang

0 0 110

- vừa được xem lúc

[MSDP] - CQRS Pattern

Trong bài viết này chúng ta sẽ cùng thảo luận về design pattern CQRS, đây là một Microservice Design Pattern để chia việc đọc và ghi dữ liệu trong ứng dụng một cách độc lập và lược đồ hóa dữ liệu một

0 0 57