那些年背过的题:Spring事务-事务传播行为底层源码分析

326 阅读4分钟

Spring定义了七种事务传播行为,主要有:

  • REQUIRED
  • REQUIRES_NEW
  • NESTED
  • SUPPORTS
  • NOT_SUPPORTED
  • MANDATORY
  • NEVER

Spring事务传播行为的核心源码涉及多个关键类和方法。在深入分析这些源码之前,先要理解几个重要概念:

  1. TransactionInterceptor:事务拦截器,负责在方法调用前后处理事务逻辑。
  2. TransactionAspectSupport:事务管理的支持类,包含了大部分事务处理的核心逻辑。
  3. PlatformTransactionManager:事务管理器接口,其具体实现类负责实际的事务管理(如 DataSourceTransactionManager)。
  4. TransactionStatus:封装当前事务的状态信息。
  5. TransactionAttribute:描述事务的属性,如传播行为、隔离级别等。

1. TransactionInterceptor

TransactionInterceptor 是一个AOP方法拦截器,它会拦截带有 @Transactional 注解的方法,并在方法执行前后应用事务逻辑。核心方法是 invoke 方法。

public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        // 调用父类的 invokeWithinTransaction 方法
        return invokeWithinTransaction(invocation.getMethod(), invocation.getTargetClass(), new CoroutinesInvocationCallback() {
            @Override
            public Object proceedWithInvocation() throws Throwable {
                return invocation.proceed();
            }
        });
    }
}

2. TransactionAspectSupport

TransactionAspectSupport 包含了处理事务的核心逻辑,其中最重要的是 invokeWithinTransaction 方法。

protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation) throws Throwable {
    // 获取事务属性
    TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
    
    // 根据事务属性获取事务管理器
    PlatformTransactionManager tm = determineTransactionManager(txAttr);

    // 为事务创建事务信息
    TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);

    Object retVal;
    try {
        // 执行目标方法
        retVal = invocation.proceedWithInvocation();
    } catch (Throwable ex) {
        // 如果出现异常,回滚事务
        completeTransactionAfterThrowing(txInfo, ex);
        throw ex;
    } finally {
        // 清理事务信息
        cleanupTransactionInfo(txInfo);
    }

    // 提交事务
    commitTransactionAfterReturning(txInfo);
    return retVal;
}

3. 创建事务:createTransactionIfNecessary

这个方法负责根据需要创建新事务或加入现有事务。

protected TransactionInfo createTransactionIfNecessary(PlatformTransactionManager tm, TransactionAttribute txAttr, final String joinpointIdentification) {
    // 开始新事务或加入现有事务
    TransactionStatus status = tm.getTransaction(txAttr);

    // 创建并返回 TransactionInfo 对象
    return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
}

4. 获取事务状态:getTransaction

PlatformTransactionManager 的具体实现类(如 DataSourceTransactionManager)会在这个方法中根据事务传播行为来决定如何处理事务。

@Override
public final TransactionStatus getTransaction(TransactionDefinition definition) {
    Object transaction = doGetTransaction();

    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED) {
        if (isExistingTransaction(transaction)) {
            // 加入现有事务
            return handleExistingTransaction(definition, transaction, true);
        }
        // 创建新事务
        return startTransaction(transaction, definition);
    }
    // 其他传播行为的处理
}

5. 处理现有事务:handleExistingTransaction

根据事务传播行为处理现有事务。

private TransactionStatus handleExistingTransaction(TransactionDefinition definition, Object transaction, boolean existingTransaction) {
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
        // 挂起当前事务,并开始新事务
        SuspendedResourcesHolder suspendedResources = suspend(transaction);
        return startTransaction(transaction, definition, suspendedResources);
    }
    // 其他传播行为的处理
}

6. 提交事务:commitTransactionAfterReturning

当方法成功执行后,提交事务。

protected void commitTransactionAfterReturning(TransactionInfo txInfo) {
    if (txInfo != null && txInfo.hasTransaction()) {
        txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
    }
}

7. 回滚事务:completeTransactionAfterThrowing

当方法抛出异常时,回滚事务。

protected void completeTransactionAfterThrowing(TransactionInfo txInfo, Throwable ex) {
    if (txInfo != null && txInfo.hasTransaction()) {
        try {
            txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
        } catch (TransactionSystemException ex2) {
            logger.error("Application exception overridden by rollback exception", ex);
            ex.addSuppressed(ex2);
            throw ex;
        } catch (RuntimeException | Error ex3) {
            logger.error("Application exception overridden by rollback exception", ex);
            throw ex3;
        }
    }
}

8. 清理事务信息:cleanupTransactionInfo

在事务完成后,清理事务相关信息。

private void cleanupTransactionInfo(TransactionInfo txInfo) {
    if (txInfo != null) {
        txInfo.clearTransaction();
    }
}

9. 事务管理器接口:PlatformTransactionManager

Spring提供了多个实现类,比如 DataSourceTransactionManagerJpaTransactionManager 等,这些实现类负责具体的事务管理操作。下面是 PlatformTransactionManager 接口定义:

public interface PlatformTransactionManager {
    TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
    void commit(TransactionStatus status) throws TransactionException;
    void rollback(TransactionStatus status) throws TransactionException;
}

10. 示例:DataSourceTransactionManager

DataSourceTransactionManager 为例,它是常见的关系型数据库事务管理器。

public class DataSourceTransactionManager extends AbstractPlatformTransactionManager {

    @Override
    protected Object doGetTransaction() {
        DataSourceTransactionObject txObject = new DataSourceTransactionObject();
        ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(this.getDataSource());
        txObject.setConnectionHolder(conHolder, false);
        return txObject;
    }

    @Override
    protected void doBegin(Object transaction, TransactionDefinition definition) {
        DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
        Connection con = DataSourceUtils.getConnection(this.getDataSource());
        txObject.setConnectionHolder(new ConnectionHolder(con), true);
    }

    @Override
    protected void doCommit(DefaultTransactionStatus status) {
        DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
        Connection con = txObject.getConnectionHolder().getConnection();
        con.commit();
    }

    @Override
    protected void doRollback(DefaultTransactionStatus status) {
        DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
        Connection con = txObject.getConnectionHolder().getConnection();
        con.rollback();
    }
}

11. 综合流程图

为了全面展示Spring事务传播行为的处理流程,以下是一个综合流程图,以帮助理解整个事务管理过程:

+-------------------+
| MethodInvocation  |
+-------------------+
           |
           v
+----------------------------+
| TransactionInterceptor     |
| - invoke                   |
+----------------------------+
           |
           v
+----------------------------------------+
| TransactionAspectSupport               |
| - invokeWithinTransaction              |
+----------------------------------------+
           |
           v
+----------------------------------------------+
| PlatformTransactionManager                  |
| - getTransaction                             |
| - createTransactionIfNecessary               |
+----------------------------------------------+
           |
           v
+----------------------------------------------------+
| Determine and Apply Propagation Behavior           |
| - handleExistingTransaction                        |
| - startTransaction                                 |
+----------------------------------------------------+
           |
           v
+---------------------+
| Execute Target      |
| Method              |
+---------------------+
           |
           v
+-------------------------------+
| Complete Transaction          |
| - commitTransactionAfterReturning |
| - completeTransactionAfterThrowing|
+-------------------------------+
           |
           v
+---------------------------+
| Cleanup Transaction Info  |
| - cleanupTransactionInfo  |
+---------------------------+

12. 流程解释

  1. MethodInvocation:方法调用被AOP拦截器拦截。
  2. TransactionInterceptor:事务拦截器开始处理,调用父类的 invokeWithinTransaction 方法。
  3. TransactionAspectSupport:处理事务逻辑,包括获取事务属性和管理事务状态。
  4. PlatformTransactionManager:根据事务属性确定是否创建新事务或加入现有事务。
  5. Determine and Apply Propagation Behavior:根据传播行为(如 REQUIREDREQUIRES_NEW 等)来处理事务。
  6. Execute Target Method:执行目标方法。
  7. Complete Transaction:根据方法执行结果决定提交或回滚事务。
  8. Cleanup Transaction Info:清理事务信息。