You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求Spring Boot Microservices Saga项目可运行POC源码示例

以下提供两种主流Saga实现模式的极简可运行POC,无冗余依赖,逻辑清晰易懂,你可以直接在本地搭建运行:

1. 协同式Saga POC(基于Spring Boot + Kafka)

不需要引入额外的编排组件,通过服务之间传递事件完成流程流转,适合轻量化场景。

项目结构

  • 3个独立Spring Boot微服务:订单服务、库存服务、支付服务
  • 统一依赖:spring-boot-starter-web、spring-kafka、lombok、spring-boot-starter-data-jpa、h2(内存数据库)

核心代码片段

订单服务核心逻辑

@Service
public class OrderService {
    private final KafkaTemplate<String, Object> kafkaTemplate;
    private final OrderRepository orderRepository;

    public Order createOrder(OrderCreateDTO request) {
        Order order = new Order();
        order.setStatus("CREATED");
        order.setUserId(request.getUserId());
        order.setProductId(request.getProductId());
        order.setAmount(request.getAmount());
        order.setTotalPrice(request.getAmount() * request.getUnitPrice());
        orderRepository.save(order);
        // 发布订单创建事件
        kafkaTemplate.send("order_created", order);
        return order;
    }

    // 补偿监听:取消订单
    @KafkaListener(topics = "order_cancel")
    public void handleOrderCancel(Order order) {
        order.setStatus("CANCELLED");
        orderRepository.save(order);
    }

    // 完成订单监听
    @KafkaListener(topics = "order_complete")
    public void handleOrderComplete(Order order) {
        order.setStatus("COMPLETED");
        orderRepository.save(order);
    }
}

库存服务核心逻辑

@Service
public class InventoryService {
    private final KafkaTemplate<String, Object> kafkaTemplate;
    private final InventoryRepository inventoryRepository;

    @KafkaListener(topics = "order_created")
    public void handleOrderCreate(Order order) {
        Inventory inventory = inventoryRepository.findByProductId(order.getProductId());
        if (inventory.getStock() >= order.getAmount()) {
            // 扣减库存
            inventory.setStock(inventory.getStock() - order.getAmount());
            inventoryRepository.save(inventory);
            // 发布库存扣减成功事件
            kafkaTemplate.send("inventory_deducted", order);
        } else {
            // 库存不足,触发订单取消补偿
            kafkaTemplate.send("order_cancel", order);
        }
    }

    // 补偿监听:回滚库存
    @KafkaListener(topics = "inventory_rollback")
    public void handleInventoryRollback(Order order) {
        Inventory inventory = inventoryRepository.findByProductId(order.getProductId());
        inventory.setStock(inventory.getStock() + order.getAmount());
        inventoryRepository.save(inventory);
    }
}

支付服务核心逻辑

@Service
public class PaymentService {
    private final KafkaTemplate<String, Object> kafkaTemplate;
    private final PaymentRepository paymentRepository;

    @KafkaListener(topics = "inventory_deducted")
    public void handleInventoryDeducted(Order order) {
        Payment payment = paymentRepository.findByUserId(order.getUserId());
        if (payment.getBalance() >= order.getTotalPrice()) {
            // 扣减余额
            payment.setBalance(payment.getBalance() - order.getTotalPrice());
            paymentRepository.save(payment);
            // 所有步骤完成,发布订单完成事件
            kafkaTemplate.send("order_complete", order);
        } else {
            // 余额不足,触发两级补偿
            kafkaTemplate.send("inventory_rollback", order);
            kafkaTemplate.send("order_cancel", order);
        }
    }
}
2. 编排式Saga POC(基于Spring Boot + Axon Framework)

由中心化编排器统一控制Saga流程和补偿逻辑,适合复杂业务场景,框架自动管理Saga生命周期和状态。

项目依赖

  • 核心依赖:spring-boot-starter-web、axon-spring-boot-starter、lombok、h2(内存数据库存储Saga状态和事件)

核心Saga编排代码

@Saga
public class OrderProcessingSaga {
    @Autowired
    private transient CommandGateway commandGateway;

    // 订单创建事件触发Saga启动
    @StartSaga
    @SagaEventHandler(associationProperty = "orderId")
    public void handleOrderCreated(OrderCreatedEvent event) {
        // 发送扣减库存命令
        commandGateway.send(new DeductInventoryCommand(
            event.getOrderId(),
            event.getProductId(),
            event.getAmount()
        ));
    }

    // 库存扣减成功后触发扣减余额
    @SagaEventHandler(associationProperty = "orderId")
    public void handleInventoryDeducted(InventoryDeductedEvent event) {
        commandGateway.send(new DeductBalanceCommand(
            event.getOrderId(),
            event.getUserId(),
            event.getTotalPrice()
        ));
    }

    // 余额扣减成功,Saga完成
    @SagaEventHandler(associationProperty = "orderId")
    public void handleBalanceDeducted(BalanceDeductedEvent event) {
        commandGateway.send(new CompleteOrderCommand(event.getOrderId()));
        SagaLifecycle.end();
    }

    // 库存扣减失败,直接取消订单
    @SagaEventHandler(associationProperty = "orderId")
    public void handleInventoryDeductFailed(InventoryDeductFailedEvent event) {
        commandGateway.send(new CancelOrderCommand(event.getOrderId()));
        SagaLifecycle.end();
    }

    // 余额扣减失败,先回滚库存再取消订单
    @SagaEventHandler(associationProperty = "orderId")
    public void handleBalanceDeductFailed(BalanceDeductFailedEvent event) {
        commandGateway.send(new RollbackInventoryCommand(
            event.getOrderId(),
            event.getProductId(),
            event.getAmount()
        ));
        commandGateway.send(new CancelOrderCommand(event.getOrderId()));
        SagaLifecycle.end();
    }
}

上述两个POC都是最小实现,你可以直接在本地启动对应服务,分别模拟库存不足、余额不足、所有步骤正常三种场景,就能直观看到Saga的正向执行和反向补偿的完整逻辑。

内容的提问来源于stack exchange,提问作者Jeff Cook

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 22:51:01