Spring 事务的传播行为有哪几种?分别是什么含义?

结论先行:传播行为解决“事务方法调用另一个事务方法/普通方法”时事务边界如何传递,一共 7 种。记熟“新建系”三兄弟即可应对大多数面试:REQUIRED(默认,有事务就加入、没有就新建)、REQUIRES_NEW(挂起当前事务、另开新事务)、NESTED(嵌套事务,内层失败只回滚到保存点);其余四种 SUPPORTS、NOT_SUPPORTED、MANDATORY、NEVER 属于边界限定。

七种传播行为表

传播行为外层有事务外层无事务一句话
REQUIRED加入外层新建事务默认,同生共死
SUPPORTS加入外层非事务执行有就蹭、没有就裸跑
MANDATORY加入外层抛异常必须在事务里执行
REQUIRES_NEW挂起外层、新开新建事务内外各自独立提交
NOT_SUPPORTED挂起外层非事务执行强制不开事务
NEVER抛异常非事务执行禁止出现事务
NESTED保存点嵌套新建事务内层失败只回滚内层

代码示例:业务失败也要记录日志

@Service
public class OrderService {
    @Transactional
    public void placeOrder(Order order) {
        save(order);                 // 主事务:失败则整体回滚
        logService.writeLog(order);  // REQUIRES_NEW:独立提交,不受主事务影响
    }
}

@Service
public class LogService {
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void writeLog(Order order) {
        logMapper.insert(order);
    }
}

高频坑点

  • 同类自调用会绕过代理,传播行为与事务注解一起失效;
  • REQUIRES_NEW 内外各占一个数据库连接,连接池过小时可能互相等待甚至耗尽;
  • NESTED 依赖 JDBC 保存点能力,不同数据库/驱动支持度有差异。

常见追问 / 记忆点

  • 追问:REQUIRES_NEW 与 NESTED 的本质区别?答:前者是完全独立的新事务,内层提交后即使外层回滚也不受影响;后者是保存点机制,内层回滚只回滚到保存点,外层仍可决定整体提交或回滚。
  • 追问:默认传播行为与回滚规则?答:REQUIRED,且默认只回滚 RuntimeException 与 Error。
  • 记忆点:先记“新建系”三兄弟 REQUIRED/REQUIRES_NEW/NESTED,其余四种当“边界限定系”记。
笔记加载中…