package com.erp.example.seata; import io.seata.spring.annotation.GlobalTransactional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * 分布式事务示例 - 创建订单业务流程 * * 事务流程: * 1. 创建订单(Order) - 订单状态=PENDING * 2. 扣减库存(Inventory) - 冻结库存 * 3. 扣减账户余额(Finance) - 冻结资金 * 4. 更新订单状态 - 订单状态=CREATED * * 如果任何步骤失败,Seata会自动回滚所有已执行的步骤 */ @Service public class GlobalTransactionalExample { private static final Logger log = LoggerFactory.getLogger(GlobalTransactionalExample.class); @Autowired private OrderService orderService; @Autowired private InventoryService inventoryService; @Autowired private FinanceService financeService; /** * 创建订单并执行分布式事务 * * @param customerId 客户ID * @param productId 商品ID * @param quantity 购买数量 * @return 订单编号 */ @GlobalTransactional(name = "create-order-transaction", timeoutMills = 30000, rollbackFor = Exception.class) public String createOrder(Long customerId, Long productId, Integer quantity) { log.info("========== 开始分布式事务 =========="); log.info("客户ID: {}, 商品ID: {}, 数量: {}", customerId, productId, quantity); // 1. 创建订单 String orderNo = orderService.createOrder(customerId, productId, quantity); log.info("订单已创建: {}", orderNo); // 2. 扣减库存(AT模式自动补偿) inventoryService.reserveStock(productId, quantity, orderNo); log.info("库存已冻结: 商品{} 数量{}", productId, quantity); // 3. 冻结资金(AT模式自动补偿) financeService.freezeAmount(customerId, quantity * 100L, orderNo); log.info("资金已冻结: 客户{} 金额{}", customerId, quantity * 100L); // 4. 更新订单状态 orderService.updateOrderStatus(orderNo, "CREATED"); log.info("订单状态已更新: {} -> CREATED", orderNo); log.info("========== 分布式事务完成 =========="); return orderNo; } /** * 模拟失败场景 - 演示事务回滚 */ @GlobalTransactional(name = "create-order-rollback-demo", timeoutMills = 30000) public void createOrderRollbackDemo(Long customerId, Long productId, Integer quantity) { log.info("========== 开始分布式事务(会回滚)=========="); String orderNo = orderService.createOrder(customerId, productId, quantity); log.info("订单已创建: {}", orderNo); // 这里会抛出异常,触发全局回滚 inventoryService.reserveStock(productId, quantity, orderNo); financeService.freezeAmount(customerId, quantity * 100L, orderNo); // 模拟业务异常 throw new RuntimeException("业务处理异常,触发全局回滚!"); } }