Skip to content

03.3 传播行为与隔离级别

本章深入 7 种传播行为的源码实现、事务的挂起与恢复机制、以及各传播行为是否新建物理连接的底层分析。


1. 事务的挂起与恢复(suspend / resume)

挂起的核心代码

java
// AbstractPlatformTransactionManager.suspend()
@Nullable
protected final SuspendedResourcesHolder suspend(@Nullable Object transaction) 
        throws TransactionException {
    
    if (TransactionSynchronizationManager.isSynchronizationActive()) {
        // 1. 触发所有同步器的 suspend 回调
        List<TransactionSynchronization> suspendedSynchronizations = 
            TransactionSynchronizationManager.getSynchronizations();
        for (TransactionSynchronization synchronization : suspendedSynchronizations) {
            synchronization.suspend();
        }
        // 2. 清空当前线程的同步器
        TransactionSynchronizationManager.clearSynchronization();
    }
    
    // 3. 解绑并保存资源(ConnectionHolder 等)
    Map<Object, Object> suspendedResources = null;
    if (transaction != null) {
        suspendedResources = TransactionSynchronizationManager.getResourceMap().isEmpty() ? 
            null : new HashMap<>(TransactionSynchronizationManager.getResourceMap());
        // 解绑所有资源
        // 这样后续的 DAO 操作就拿不到旧连接了
    }
    
    // 4. 保存事务名称/只读/隔离级别/活跃状态
    String suspendedName = TransactionSynchronizationManager.getCurrentTransactionName();
    TransactionSynchronizationManager.setCurrentTransactionName(null);
    
    Boolean suspendedReadOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
    TransactionSynchronizationManager.setCurrentTransactionReadOnly(null);
    
    Integer suspendedIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
    TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(null);
    
    Boolean suspendedActive = TransactionSynchronizationManager.isActualTransactionActive();
    TransactionSynchronizationManager.setActualTransactionActive(false);
    
    // 5. 将所有保存的信息包装返回
    return new SuspendedResourcesHolder(
        suspendedResources, suspendedSynchronizations, 
        suspendedName, suspendedReadOnly, suspendedIsolationLevel, suspendedActive);
}

2. Propagation 行为源码级对比

传播行为handleExistingTransaction 处理isNewTransaction底层行为是否新建连接
REQUIRED直接返回,不做操作(加入)false共享同一 Connection
REQUIRES_NEWsuspend() → 解绑旧连接 → doBegin() 获取新连接true使用全新 Connection
NESTEDcreateAndHoldSavepoint() → 设置 JDBC 保存点false同一 Connection 不同保存点
NOT_SUPPORTEDsuspend() → 非事务运行false挂起事务,无事务运行❌(暂不绑定)
SUPPORTS直接返回,不做操作false同 REQUIRED 但无事务
MANDATORY直接返回,不做操作false同 REQUIRED
NEVER抛异常拒绝事务上下文

核心面试题

  1. REQUIRES_NEW 在同一个事务管理器下真的会新建物理连接吗?挂起和恢复的机制?
  2. NESTED 传播行为底层如何实现?如何做到只回滚部分操作?
  3. Spring 事务传播行为执行流程对比:REQUIRED、REQUIRES_NEW、NESTED 的区别?

← 返回 **返回 事务管理索引**

Knowledge4J — Java 知识库