Spring事务传播机制完全指南:7种策略解决你的业务数据难题

282 阅读2分钟

事务传播策略选择树.png

一、7大传播机制速览

1. REQUIRED(默认)

  • 行为:存在事务则加入,没有则新建
  • 场景:90%的数据库操作(如订单创建+库存扣减
@Transactional(propagation = Propagation.REQUIRED)
public void createOrder(Order order) {
    // 订单表和库存表同时更新
}

2. REQUIRES_NEW

  • 行为:始终新建独立事务
  • 场景:日志记录(即使主事务回滚,日志仍需保存
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void saveOperationLog(Log log) {
    // 独立事务记录操作日志
}

3. NESTED

  • 行为:嵌套事务(支持部分回滚)
  • 场景:电商订单多步骤提交(如先存主订单,再存子订单
@Transactional(propagation = Propagation.NESTED)
public void saveSubOrder(SubOrder subOrder) {
    // 子订单保存失败不影响主订单
}

4. SUPPORTS

  • 行为:有事务就加入,没有则以非事务运行
  • 场景:数据查询(不需要强一致性时
@Transactional(propagation = Propagation.SUPPORTS)
public List<Order> queryOrders() {
    // 可运行在事务或非事务环境
}

5. NOT_SUPPORTED

  • 行为:非事务方式执行,挂起当前事务
  • 场景:大数据量导出(避免长事务锁表
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void exportBigData() {
    // 长时间数据导出操作
}

6. MANDATORY

  • 行为:必须存在事务,否则抛异常
  • 场景:资金账户变更(强制要求事务环境
@Transactional(propagation = Propagation.MANDATORY)
public void updateBalance() {
    // 必须在事务中执行
}

7. NEVER

  • 行为:禁止事务,存在事务则抛异常
  • 场景:性能敏感计算(避免事务开销)
@Transactional(propagation = Propagation.NEVER)
public void calculateStatistics() {
    // 纯内存计算操作
}

二、实战案例解析(电商下单场景)

下单流程事务传播策略.png 代码实现

@Transactional(rollbackFor = Exception.class)
public void createOrder(OrderMain order, List<OrderItem> items) {
    // 1. 保存主订单(REQUIRED)
    orderMapper.insert(order);
    
    // 2. 扣减库存(REQUIRED)
    stockService.deductStock(items);
    
    try {
        // 3. 使用优惠券(NESTED)
        couponService.useCoupon(order.getCouponId());
    } catch (Exception e) {
        // 仅回滚优惠券操作,不影响主订单
    }
    
    // 4. 记录操作日志(REQUIRES_NEW)
    logService.saveLog(new OrderLog(order));
}

三、传播机制对照表

策略当前存在事务异常回滚范围适用场景
REQUIRED加入整个事务通用数据库操作
REQUIRES_NEW新建仅当前事务独立业务(如日志)
NESTED嵌套当前保存点多步骤事务
SUPPORTS加入跟随外层事务数据查询
NOT_SUPPORTED挂起不参与事务非关键操作
MANDATORY必须存在整个事务强制事务环境
NEVER禁止存在不涉及非事务操作

四、选择策略的4个黄金法则

  1. 主从业务分离:核心业务用REQUIRED,辅助功能用REQUIRES_NEW
  2. 异常隔离需求:需要部分回滚时使用NESTED
  3. 性能优先场景:非关键操作使用NOT_SUPPORTEDNEVER
  4. 强一致性要求:资金操作必须使用MANDATORY

通过合理选择传播策略,既能保证数据一致性,又能提升系统性能。下次遇到事务混乱问题时,不妨根据这个指南重新梳理您的业务逻辑!