Outbox Pattern

Overview

  • Outbox 是一個資料表
  • 存儲待發布的事件
CREATE TABLE outbox (
    id UUID PRIMARY KEY,
    aggregate_type VARCHAR(255), -- 如 "Order"
    aggregate_id UUID,           -- 如 訂單ID
    event_type VARCHAR(255),     -- 如 "OrderCreated"
    payload JSONB,               -- 事件數據
    status VARCHAR(50),          -- PENDING/PUBLISHED/FAILED
    created_at TIMESTAMP,
    published_at TIMESTAMP NULL
);

Sequence Diagram

  sequenceDiagram
   participant Client
   participant OrderService
   participant DB as Order Database
   participant Publisher
   participant MQ as Kafka / RabbitMQ / JetStream
   participant InventoryService
   participant PaymentService
   participant NotificationService

   %% Initial Order Creation
   Client->>+OrderService: Create Order
   OrderService->>+DB: Begin Transaction

   rect rgba(0, 255, 0, 0.1)
       Note over OrderService,DB: Transaction Boundary
       OrderService->>DB: Insert Order
       OrderService->>DB: Insert to Outbox Table
       DB-->>OrderService: Commit Success
   end

   OrderService-->>-Client: Order Created (202 Accepted)

   %% CDC & Message Publishing
   rect rgba(0, 0, 255, 0.1)
       Note over DB,Publisher: CDC Process
       DB->>Publisher: CDC Event (New Outbox Record)
       Publisher->>MQ: Publish OrderCreated Event
       Publisher->>DB: Update Outbox Status (Published)
   end

   %% Event Processing by Services
   par Parallel Processing
       MQ-->>InventoryService: Consume OrderCreated
       MQ-->>PaymentService: Consume OrderCreated
       MQ-->>NotificationService: Consume OrderCreated
   end

   %% Service Processing
   rect rgba(255, 0, 0, 0.1)
       Note over InventoryService: Local Transaction
       InventoryService->>InventoryService: Reserve Stock
   end

   rect rgba(255, 0, 0, 0.1)
       Note over PaymentService: Local Transaction
       PaymentService->>PaymentService: Process Payment
   end

   rect rgba(255, 0, 0, 0.1)
       Note over NotificationService: Local Transaction
       NotificationService->>NotificationService: Send Notification
   end

   %% Service Responses
   par Service Responses
       InventoryService->>MQ: Publish StockReserved
       PaymentService->>MQ: Publish PaymentProcessed
       NotificationService->>MQ: Publish NotificationSent
   end

   %% Order Status Update
   MQ-->>OrderService: Consume Events
   OrderService->>DB: Update Order Status

   %% Error Handling
   opt Error in Payment
       PaymentService->>MQ: Publish PaymentFailed
       MQ-->>OrderService: Consume PaymentFailed
       OrderService->>DB: Update Order Status (Failed)
       OrderService->>MQ: Publish OrderCancelled
       par Compensating Transactions
           MQ-->>InventoryService: Release Stock
           MQ-->>NotificationService: Send Cancellation Notice
       end
   end

   %% Retry Mechanism
   loop Retry Failed Events
       Publisher->>DB: Query Failed Events
       Publisher->>MQ: Retry Publishing
   end