Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 64

Thiết kế quy trình BPMN cho Saga - Giao dịch xuôi

Recommended resources

Chào bạn,

Trong bài học trước, chúng ta đã cùng nhau tìm hiểu lý thuyết về Saga pattern - một mẫu thiết kế kiến trúc cực kỳ quan trọng để đảm bảo tính nhất quán dữ liệu trong môi trường microservices. Bạn đã biết rằng Saga là một chuỗi các giao dịch cục bộ (local transactions) và có hai kiểu điều phối chính là Orchestration và Choreography.

Hôm nay, chúng ta sẽ vận dụng những kiến thức đó vào thực tế. Mục tiêu của bài học này là thiết kế một quy trình BPMN cho các giao dịch xuôi (forward transactions) của một Saga. Nói cách khác, chúng ta sẽ học cách mô hình hóa "luồng đi thuận" hay "happy path" của một Saga, nơi mà mọi thứ diễn ra thành công, bằng cách sử dụng Camunda. Đây là bước đầu tiên và cơ bản nhất để xây dựng một Saga orchestrator hoàn chỉnh.


1. Quy trình BPMN trong vai trò Saga Orchestrator

Trong Saga pattern theo kiểu Orchestration, chúng ta cần một thành phần trung tâm để điều phối toàn bộ luồng công việc. Với Camunda, quy trình BPMN chính là một Saga Orchestrator hoàn hảo. Process engine sẽ chịu trách nhiệm:

  • Ra lệnh cho các microservices thực hiện các giao dịch cục bộ.
  • Lưu trữ trạng thái của toàn bộ Saga (ví dụ: bước nào đã hoàn thành, bước nào đang chạy).
  • Quyết định bước tiếp theo dựa trên kết quả trả về.

Mỗi bước trong chuỗi giao dịch xuôi của Saga sẽ được mô hình hóa thành một hoặc nhiều phần tử trong sơ đồ BPMN của chúng ta.


2. Mô hình hóa Giao dịch xuôi với Service Task

Cách đơn giản nhất để biểu diễn một giao dịch cục bộ trong Saga là sử dụng Service Task. Mỗi Service Task sẽ đại diện cho một lời gọi đến một microservice để thực hiện một công việc cụ thể.

Hãy xem xét ví dụ kinh điển về đặt một chuyến đi du lịch, bao gồm: đặt xe, đặt khách sạn và đặt vé máy bay. Luồng giao dịch xuôi sẽ là một chuỗi các Service Task nối tiếp nhau.

BPMN and Microservices Orchestration, Part 2 of 2

Bài viết này từ blog của Camunda cung cấp một ví dụ rất trực quan về việc mô hình hóa Saga pattern bằng BPMN. Hãy xem sơ đồ để thấy cách các giao dịch xuôi được thể hiện.

Hãy đọc phần 'The Saga Pattern Simplified' và chú ý đến sơ đồ BPMN có tên 'Compensation event and saga pattern in BPMN'. Tập trung vào luồng chính đi từ trái sang phải: 'Reserve car', 'Book hotel', 'Book flight'. Đây chính là chuỗi các giao dịch xuôi (forward transactions) của chúng ta. Tạm thời bạn có thể bỏ qua các biểu tượng hình mũi tên quay lại được đính kèm với các task, chúng ta sẽ tìm hiểu về chúng trong bài học tiếp theo.

Như bạn thấy trong sơ đồ từ bài viết, luồng đi chính rất đơn giản và dễ đọc: Reserve car -> Book hotel -> Book flight. Đây chính là bản chất của việc mô hình hóa các giao dịch xuôi. Mỗi Service Task này sẽ được liên kết với một đoạn code (ví dụ: một lớp Java delegate hoặc một external task worker) để gọi đến API của microservice tương ứng.


3. Mô hình hóa Giao tiếp Bất đồng bộ với Send/Receive Task

Trong thực tế, kiến trúc microservices thường ưu tiên giao tiếp bất đồng bộ (asynchronous) thông qua một message broker (như Kafka, RabbitMQ, Pulsar) để tăng tính linh hoạt và khả năng phục hồi. Orchestrator sẽ gửi một lệnh (command) và chờ đợi một sự kiện (event) phản hồi.

BPMN cung cấp các phần tử chuyên dụng cho kịch bản này:

  • Send Task: Dùng để gửi một thông điệp (command) đến một service.
  • Receive Task hoặc Intermediate Message Catch Event: Dùng để chờ nhận một thông điệp (event) phản hồi trước khi tiếp tục.

Luồng đặt chuyến đi ở trên có thể được mô hình hóa lại như sau:
Start -> Send Task 'Reserve Car' -> Receive Task 'Car Reserved' -> Send Task 'Book Hotel' -> Receive Task 'Hotel Booked' -> ... -> End

🚀 Saga Orchestration in Microservices Explained with Real Movie Booking Example 🎬

Để hình dung rõ hơn về luồng đi của các lệnh và sự kiện trong một Saga orchestration, hãy xem video này. Video sử dụng ví dụ đặt vé xem phim và minh họa cách 'Orchestrator' gửi lệnh và nhận phản hồi từ các microservices khác nhau.

Hãy xem từ 02:56 đến 06:27. Phần này sẽ trình bày toàn bộ luồng xử lý trên một sơ đồ kiến trúc. Chú ý đến các mũi tên màu xanh lá cây (success path) - chúng biểu diễn các giao dịch xuôi: Orchestrator gửi lệnh đặt chỗ (seat reservation command). Seat Service xử lý và gửi lại sự kiện thành công (success event). Orchestrator nhận sự kiện thành công, sau đó gửi lệnh thanh toán (payment command). Payment Service xử lý và gửi lại sự kiện thành công. Orchestrator xác nhận đơn hàng cuối cùng. Đây chính là logic bạn sẽ mô hình hóa bằng các cặp Send Task và Receive Task trong BPMN.

Cách tiếp cận này giúp tách biệt rõ ràng hành động "gửi lệnh đi" và "chờ kết quả", phản ánh chính xác hơn bản chất bất đồng bộ của hệ thống.

BPMN Diagram of a Saga Pattern for Trip Booking
Một cách mô hình hóa khác cho giao dịch xuôi là sử dụng Exclusive Gateway sau mỗi bước để kiểm tra kết quả ('Successful?'). Nếu thành công, luồng đi tiếp; nếu thất bại, nó sẽ rẽ sang nhánh xử lý lỗi/bù trừ. Đây cũng là một mẫu thiết kế rất phổ biến.

4. Xử lý các Giao dịch Song song

Không phải lúc nào các giao dịch xuôi cũng cần thực hiện tuần tự. Nếu hai hoặc nhiều hành động không phụ thuộc vào nhau, chúng ta có thể thực hiện chúng song song để tăng hiệu suất.

Ví dụ, trong quy trình tạo đơn hàng, các hành động "Tạo khách hàng mới" và "Kiểm tra tồn kho" có thể diễn ra đồng thời. BPMN cung cấp Parallel Gateway để mô hình hóa chính xác kịch bản này.

  • Parallel Gateway (Fork): Tách luồng thực thi ra nhiều nhánh chạy song song.
  • Parallel Gateway (Join): Chờ tất cả các nhánh song song hoàn thành rồi mới gộp luồng thực thi lại.

Saga Pattern with Camunda and Apache Pulsar

Bài viết này đi sâu vào việc triển khai Saga Pattern với Camunda, sử dụng giao tiếp bất đồng bộ. Nó chứa các sơ đồ BPMN rất chi tiết, thể hiện cả việc sử dụng các cặp Send/Receive Task và Parallel Gateway.

Hãy lướt qua bài viết, đặc biệt chú ý đến các sơ đồ BPMN trong phần 'Positive Scenario'. Quan sát cách tác giả sử dụng: Một Parallel Gateway để tách ra các luồng 'Create Customer', 'Calculate Product Options', 'Reserve Product in Inventory', 'Create Invoice'. Các cặp Send Task (ví dụ 'Create Customer') và Receive Task (ví dụ 'Customer Created') cho mỗi nhánh. Một Parallel Gateway khác để hợp nhất các luồng lại. Bạn không cần đọc hiểu toàn bộ code, chỉ cần tập trung vào cách các phần tử BPMN được kết hợp để tạo nên một luồng giao dịch xuôi phức tạp nhưng rõ ràng.

Bằng cách sử dụng Parallel Gateway, bạn có thể thiết kế các quy trình Saga hiệu quả hơn, tận dụng được khả năng xử lý đồng thời của kiến trúc microservices.



Tổng kết

Qua bài học này, bạn đã nắm được các kỹ thuật cốt lõi để thiết kế phần "giao dịch xuôi" của một Saga orchestration bằng BPMN. Các điểm chính cần nhớ:

  • Quy trình BPMN là Orchestrator: Nó điều phối, ra lệnh và theo dõi trạng thái của Saga.
  • Mô hình hóa giao dịch:
    • Service Task: Cách tiếp cận đơn giản và trực tiếp, phù hợp cho các lời gọi đồng bộ.
    • Send Task / Receive Task: Phản ánh chính xác kiến trúc giao tiếp bất đồng bộ, event-driven.
  • Tối ưu hóa luồng:
    • Parallel Gateway: Cho phép thực thi song song các giao dịch cục bộ độc lập để cải thiện hiệu suất.

Việc thiết kế một luồng "happy path" rõ ràng, dễ hiểu là nền tảng vững chắc cho một Saga đáng tin cậy.


Xem trước bài học tiếp theo

Chúng ta đã biết cách mô hình hóa kịch bản khi mọi thứ suôn sẻ. Nhưng câu hỏi lớn nhất của Saga pattern là: "Khi có lỗi xảy ra thì sao?". Trong bài học tiếp theo, chúng ta sẽ giải quyết phần còn lại của bài toán: Sử dụng Compensation Events để implement các giao dịch bù trừ (compensating transactions). Bạn sẽ học cách thiết kế và kích hoạt logic "hoàn tác" một cách trực quan ngay trên sơ đồ BPMN.