分布式事务挑战与解决方案

在微服务架构中,跨服务的数据一致性是一个核心挑战。RuoYI-cloud 通过集成 Seata 框架,提供了可靠的分布式事务解决方案,确保多个服务间的操作要么全部成功,要么全部回滚。

Seata 核心架构

Seata 定义了三个核心角色来实现分布式事务管理:

  1. Transaction Coordinator (TC) - 事务协调器
  • 作为独立服务运行
  • 负责全局事务的管理、协调和调度
  • 维护全局事务和分支事务的状态
  1. Transaction Manager (TM) - 事务管理器
  • 嵌入在应用中(如订单服务)
  • 负责发起全局事务
  • 决定全局事务的提交或回滚
  1. Resource Manager (RM) - 资源管理器
  • 嵌入在应用中(如库存服务)
  • 负责管理分支事务
  • 向 TC 注册分支事务
  • 执行分支事务的提交或回滚

代码实现示例

1. 订单服务(TM 角色)

java@Servicepublic class OrderServiceImpl implements OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate StockClient stockClient; // 调用库存服务的Feign客户端@GlobalTransactional(name = "create-order", rollbackFor = Exception.class)@Overridepublic void createOrder(OrderCreateDTO orderDTO) {// 1. 创建订单(本地事务)Order order = new Order();order.setUserId(orderDTO.getUserId());order.setProductId(orderDTO.getProductId());order.setQuantity(orderDTO.getQuantity());order.setStatus(OrderStatus.CREATED);orderMapper.insert(order);// 2. 调用库存服务扣减库存(分布式事务分支)try {stockClient.deductStock(orderDTO.getProductId(), orderDTO.getQuantity());} catch (Exception e) {throw new RuntimeException("库存扣减失败", e);}// 3. 其他业务逻辑...}}

2. 库存服务(RM 角色)

java@Servicepublic class StockServiceImpl implements StockService {@Autowiredprivate StockMapper stockMapper;@Transactional(rollbackFor = Exception.class) // 本地事务注解@Overridepublic void deductStock(Long productId, Integer quantity) {// 1. 查询库存Stock stock = stockMapper.selectByProductId(productId);if (stock == null || stock.getAvailable() < quantity) {throw new RuntimeException("库存不足");}// 2. 扣减库存stock.setAvailable(stock.getAvailable() - quantity);stockMapper.updateById(stock);// 3. 其他业务逻辑...}}

3. 库存服务控制器

java@RestController@RequestMapping("/api/stock")public class StockController {@Autowiredprivate StockService stockService;@PostMapping("/deduct")public Result deductStock(@RequestBody StockDeductDTO dto) {try {stockService.deductStock(dto.getProductId(), dto.getQuantity());return Result.success("库存扣减成功");} catch (Exception e) {return Result.error(e.getMessage());}}}

工作原理

  1. 事务发起:订单服务通过 @GlobalTransactional 注解发起全局事务
  2. 分支注册
  • 订单服务的本地操作作为第一个分支事务
  • 调用库存服务时,Seata 会自动将库存操作注册为第二个分支事务
  1. 执行阶段
  • 所有分支事务正常执行
  • TC 记录事务状态
  1. 提交/回滚
  • 如果所有分支事务成功,TC 通知所有 RM 提交分支事务
  • 如果任一分支事务失败,TC 通知所有 RM 回滚分支事务

配置要点

  1. Seata Server 部署
  • 下载并启动 Seata Server
  • 配置注册中心(如 Nacos)
  1. 客户端配置
yaml# application.ymlseata:enabled: trueapplication-id: ruoyi-order # 应用IDtx-service-group: my_test_tx_group # 事务组名称service:vgroup-mapping:my_test_tx_group: default # 事务组映射到集群grouplist:default: 127.0.0.1:8091 # Seata Server地址registry:type: nacosnacos:server-addr: 127.0.0.1:8848namespace: publiccluster: default
  1. 数据库配置
  • 需要为每个服务创建 undo_log 表(Seata 用于存储事务回滚日志)

优势与注意事项

优势

  • 侵入性低,只需少量注解即可实现分布式事务
  • 支持多种数据源和框架
  • 性能较好,采用 AT 模式(自动生成回滚日志)

注意事项

  • 确保所有参与事务的服务都正确配置 Seata
  • 避免长时间运行的事务,防止 TC 内存溢出
  • 合理设置事务超时时间
  • 监控事务状态,及时发现和处理异常事务

通过 Seata 的集成,RuoYI-cloud 能够有效解决分布式环境下的数据一致性问题,确保业务操作的原子性和可靠性。