spring事务传播级别

Spring 的事务传播行为(Propagation)用于定义在当前方法被调用时,是否要 开启新事务,还是使用已有事务。这是控制事务嵌套、事务边界的关键。


🔁 Spring 事务传播级别一览(共 7 种)

传播行为(枚举)含义
REQUIRED(默认)如果当前有事务,则加入;没有则新建一个事务 ✅ 常用
REQUIRES_NEW始终新建一个事务,暂停外部事务
NESTED如果当前有事务,则在当前事务中嵌套(使用保存点);否则新建事务
SUPPORTS如果当前有事务,则参与;没有就非事务方式运行
NOT_SUPPORTED总是以非事务方式运行,挂起当前事务
NEVER当前存在事务时抛异常
MANDATORY当前必须有事务,否则抛异常

📘 实战示例

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void saveNewUser(User user) {
    userRepository.save(user);
}


✅ 推荐使用场景

传播级别推荐使用场景
REQUIRED大多数业务方法(默认)
REQUIRES_NEW写操作独立提交,不影响主事务(如日志记录)
NESTED出错时回滚当前操作但不影响主事务(依赖数据库支持保存点)
SUPPORTS查询类操作、工具方法,可有可无事务
NOT_SUPPORTED调用第三方服务、耗时操作等不希望参与事务
MANDATORY强制在事务中调用(比如必须由主业务控制)

🎯 多事务传播执行示意图

假设:ServiceA 调用 ServiceB

  • ServiceA @Transactional(REQUIRED)
  • ServiceB @Transactional(REQUIRES_NEW)

效果:ServiceA 的事务和 ServiceB 的事务完全独立,ServiceB 的提交或回滚不会影响 ServiceA。


🧠 实用小贴士

  • Spring 事务传播机制底层依赖的是 TransactionManager 和 AOP 代理机制
  • 对于 REQUIRES_NEWNESTED,注意 数据源是否支持嵌套事务或保存点(如 JDBC + MySQL 默认支持)。
  • 嵌套事务不等于独立事务,它是依附于外层事务的一部分,只有在外层不回滚时才提交。

🔄 示例代码片段

@Service
public class OrderService {

    @Autowired
    private PaymentService paymentService;

    @Transactional
    public void createOrder() {
        // 使用默认的 REQUIRED
        orderRepository.save(...);

        // 独立事务处理支付,不影响订单主事务
        paymentService.pay(); // pay() 使用 REQUIRES_NEW
    }
}

@Service
public class PaymentService {
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void pay() {
        paymentRepository.save(...);
        // throw new RuntimeException(); // 只影响 pay,不影响上层
    }
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注