AbstractPlatformTransactionManager抽象事务管理器分析

上文简单看了spring为了管理事务而定义的几个重要接口规范,见spring事务接口规范,而这些规范具体的执行,就是今天要分析的一个非常重要的执行类AbstractPlatformTransactionManager,其定义了事务的具体执行逻辑,把TransactionDefinition和TransactionStatus关联了起来。

该类主要的行为:

  1. 提供方法根据事务定义TransactionDefinition创建事务,并返回事务执行状态对象TransactionStatus
  2. 提供对事务传播行为逻辑实现的模板代码
  3. 提供新建开启事务方法
  4. 提供挂起事务,恢复事务的逻辑封装
  5. 提供回调事务执行事件同步器
  6. 提供执行事务的提交或回滚模板逻辑

留给子类实现的抽象方法:

  1. doGetTransaction()
  2. isExistingTransaction()判断当前是否存在事务
  3. doBegin()开启事务模板方法
  4. doSuspend()挂起事务扩展逻辑
  5. doResume()恢复事务扩展逻辑
  6. doCommit()具体如何提交,交给子类实现
  7. doRollback()具体如何回滚,交给子类实现

参见具体实现DataSourceTransactionManager分析

定义的字段属性

public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {

    public static final int SYNCHRONIZATION_ALWAYS = 0;
	public static final int SYNCHRONIZATION_ON_ACTUAL_TRANSACTION = 1;
	public static final int SYNCHRONIZATION_NEVER = 2;
    
	private int transactionSynchronization = SYNCHRONIZATION_ALWAYS;
	private int defaultTimeout = TransactionDefinition.TIMEOUT_DEFAULT;
    //是否允许嵌入式事务(保存点的方法,不同的数据库厂商可能不同)
	private boolean nestedTransactionAllowed = false;
    // 发现存在事务时是否需要验证当前事务(当前定义与存在事务的定义属性是否相同)
	private boolean validateExistingTransaction = false;
    // 参与者失败是否全局回滚
	private boolean globalRollbackOnParticipationFailure = true;
    // 
	private boolean failEarlyOnGlobalRollbackOnly = false;
    // 提交失败是否回滚
	private boolean rollbackOnCommitFailure = false;
}

行为方法

事务开启的入口方法final TransactionStatus getTransaction(TransactionDefinition)模板方法。

@Override
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
    throws TransactionException {

    // Use defaults if no transaction definition given.
    TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());
	
    // 获取具体的事务对象(由子类实现,这里用Object接收,说明抽象类中不关心具体的事务形式)
    Object transaction = doGetTransaction();
    boolean debugEnabled = logger.isDebugEnabled();
	
    // 判断事务是否存在(子类实现,如何确定当前事务是否存在,子类自己去确定标记)
    if (isExistingTransaction(transaction)) {
        // Existing transaction found -> check propagation behavior to find out how to behave.
        // 已经存在事务的处理逻辑
        return handleExistingTransaction(def, transaction, debugEnabled);
    }

    // ------------------------当前不存在事务---------------
    // Check definition settings for new transaction.
    if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
        throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout());
    }

    // No existing transaction found -> check propagation behavior to find out how to proceed.
    if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
        
        // PROPAGATION_MANDATORY 必须在一个事务中运行,否则报错,这里抛出异常
        throw new IllegalTransactionStateException("No existing transaction found for transaction marked with propagation 'mandatory'");
    } else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
             def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
             def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
        
        // 这三种都是需要新建事务
        // 挂起当前资源(当前事务对象是null,因为这里逻辑上当前是不存在事务的,但是可能存在资源)
        SuspendedResourcesHolder suspendedResources = suspend(null);
        try {
            // 开始新的事务
            return startTransaction(def, transaction, debugEnabled, suspendedResources);
        } catch (RuntimeException | Error ex) {
            resume(null, suspendedResources);
            throw ex;
        }
    } else {
        
        // Create "empty" transaction: no actual transaction, but potentially synchronization.
        boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
        
        // 走到这里说明事务传播属性是SUPPORT(存在事务就在当前事务执行),或NOT_SUPPORT(以非事务方式运行,存在就挂起)
        return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
    }
}

 
private TransactionStatus startTransaction(TransactionDefinition definition, Object transaction,
                                           boolean debugEnabled, @Nullable SuspendedResourcesHolder suspendedResources) {

    boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
    
    // 创建事务运行时状态对象,其中保存了具体的事务对象transaction
    DefaultTransactionStatus status = newTransactionStatus(
        definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
    
    // 子类实现具体的开启事务方法
    doBegin(transaction, definition);
    // 准备同步器容器信息等
    prepareSynchronization(status, definition);
    return status;
}

protected DefaultTransactionStatus newTransactionStatus(
    TransactionDefinition definition, @Nullable Object transaction, boolean newTransaction,
    boolean newSynchronization, boolean debug, @Nullable Object suspendedResources) {

    boolean actualNewSynchronization = newSynchronization && !TransactionSynchronizationManager.isSynchronizationActive();
    return new DefaultTransactionStatus(
        transaction, newTransaction, actualNewSynchronization,
        definition.isReadOnly(), debug, suspendedResources);
}

        这个方法主要根据事务传播行为,封装了模板方法,对于当前是否存在事务有不同的逻辑,下面看当前存在事务的逻辑isExistingTransaction(transaction) = true

handleExistingTransaction()对于已经存在事务如何处理?

private TransactionStatus handleExistingTransaction(
    TransactionDefinition definition, Object transaction, boolean debugEnabled)
    throws TransactionException {
	
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
        // 正常是不会走到这里
        throw new IllegalTransactionStateException("Existing transaction found for transaction marked with propagation 'never'");
    }
	
    // 需要的是以非事务方式运行,并挂起存在的事务
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
        // 挂起事务
        Object suspendedResources = suspend(transaction);
        boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
        // 以非事务方式运行transaction=null
        return prepareTransactionStatus(definition, null, false, newSynchronization, debugEnabled, suspendedResources);
    }

    // 需要在新的单独的事务中运行(挂起存在的事务)
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
        if (debugEnabled) {
            logger.debug("Suspending current transaction, creating new transaction with name [" +
                         definition.getName() + "]");
        }
        // 挂起存在的事务
        SuspendedResourcesHolder suspendedResources = suspend(transaction);
        try {
            // 开启新事务运行
            return startTransaction(definition, transaction, debugEnabled, suspendedResources);
        }
        catch (RuntimeException | Error beginEx) {
            // 遇到异常,恢复之前挂起的事务
            resumeAfterBeginException(transaction, suspendedResources, beginEx);
            throw beginEx;
        }
    }

    // 以嵌入式的方式运行(保存点)
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
        // 判断当前厂商是否支持
        if (!isNestedTransactionAllowed()) {
            throw new NestedTransactionNotSupportedException("Transaction manager does not allow nested transactions by default -  specify 'nestedTransactionAllowed' property with value 'true'");
        }
        if (debugEnabled) {
            logger.debug("Creating nested transaction with name [" + definition.getName() + "]");
        }
        // 这里需要创建保存点(对于mysql就会在具体的连接上去创建保存点)
        if (useSavepointForNestedTransaction()) {
            // Create savepoint within existing Spring-managed transaction,
            // through the SavepointManager API implemented by TransactionStatus.
            // Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
            // 新建事务运行状态对象(还是用同一个连接,同一个具体的底层事务对象transaction)
            DefaultTransactionStatus status =
                prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
            status.createAndHoldSavepoint();
            return status;
        } else {
            // Nested transaction through nested begin and commit/rollback calls.
            // Usually only for JTA: Spring synchronization might get activated here
            // in case of a pre-existing JTA transaction.
            return startTransaction(definition, transaction, debugEnabled, null);
        }
    }

    // Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED.
    if (debugEnabled) {
        logger.debug("Participating in existing transaction");
    }
    if (isValidateExistingTransaction()) {
        if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
            // 判断隔离级别
            Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
            if (currentIsolationLevel == null || currentIsolationLevel != definition.getIsolationLevel()) {
                Constants isoConstants = DefaultTransactionDefinition.constants;
                throw new IllegalTransactionStateException("Participating transaction with definition [" + definition + "] specifies isolation level which is incompatible with existing transaction: " +  (currentIsolationLevel != null ? isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) : "(unknown)"));
            }
        }
        // 判断只读属性
        if (!definition.isReadOnly()) {
            if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
                throw new IllegalTransactionStateException("Participating transaction with definition [" + definition + "] is not marked as read-only but existing transaction is");
            }
        }
    }
    // 走到这里说明事务定义是SUPPORT(在当前事务中运行),或REQUIRED(存在,就在当前的事务中运行),或MANDATORY(必须在存在的事务中运行)
    // newSynchronization表示是否是新建的同步器(newSynchronization=true时才会触发回调事件)
    boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
    return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
}

protected final DefaultTransactionStatus prepareTransactionStatus(
    TransactionDefinition definition, @Nullable Object transaction, boolean newTransaction,
    boolean newSynchronization, boolean debug, @Nullable Object suspendedResources) {
	
    DefaultTransactionStatus status = newTransactionStatus(
        definition, transaction, newTransaction, newSynchronization, debug, suspendedResources);
    // 准备同步器容器
    prepareSynchronization(status, definition);
    return status;
}

// 创建事务运行时状态对象(持有具体的事务底层实现对象transaction)
protected DefaultTransactionStatus newTransactionStatus(
    TransactionDefinition definition, @Nullable Object transaction, boolean newTransaction,
    boolean newSynchronization, boolean debug, @Nullable Object suspendedResources) {

    boolean actualNewSynchronization = newSynchronization &&
        !TransactionSynchronizationManager.isSynchronizationActive();
    return new DefaultTransactionStatus(
        transaction, newTransaction, actualNewSynchronization,
        definition.isReadOnly(), debug, suspendedResources);
}

准备同步器容器

protected void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) {
    // 当前事务标记为新的同步器时才会执行
    if (status.isNewSynchronization()) {
        // 四大属性(ThreadLocal)
        TransactionSynchronizationManager.setActualTransactionActive(status.hasTransaction());
        TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(
            definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT ?
            definition.getIsolationLevel() : null);
        TransactionSynchronizationManager.setCurrentTransactionReadOnly(definition.isReadOnly());
        TransactionSynchronizationManager.setCurrentTransactionName(definition.getName());
        TransactionSynchronizationManager.initSynchronization();
    }
}

接下来继续分析存在事务时如何挂起当前事务(suspend)

@Nullable
protected final SuspendedResourcesHolder suspend(@Nullable Object transaction) throws TransactionException {
    if (TransactionSynchronizationManager.isSynchronizationActive()) {
        // 挂起同步器(事件监听器)
        List<TransactionSynchronization> suspendedSynchronizations = doSuspendSynchronization();
        try {
            // 挂起资源
            Object suspendedResources = null;
            if (transaction != null) {
                // 子类实现具体如何挂起底层事务对象
                suspendedResources = doSuspend(transaction);
            }
            // 暂存事务状态信息
            String name = TransactionSynchronizationManager.getCurrentTransactionName();
            TransactionSynchronizationManager.setCurrentTransactionName(null);
            
            boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
            TransactionSynchronizationManager.setCurrentTransactionReadOnly(false);
            
            Integer isolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
            TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(null);
            
            boolean wasActive = TransactionSynchronizationManager.isActualTransactionActive();
            TransactionSynchronizationManager.setActualTransactionActive(false);
            // 封装的暂存对象
            return new SuspendedResourcesHolder(suspendedResources, suspendedSynchronizations, name, readOnly, isolationLevel, wasActive);
        } catch (RuntimeException | Error ex) {
            // doSuspend failed - original transaction is still active...
            // 挂起遇到异常时,恢复
            doResumeSynchronization(suspendedSynchronizations);
            throw ex;
        }
    } else if (transaction != null) {
        // Transaction active but no synchronization active.
        Object suspendedResources = doSuspend(transaction);
        return new SuspendedResourcesHolder(suspendedResources);
    } else {
        // Neither transaction nor synchronization active.
        return null;
    }
}

private List<TransactionSynchronization> doSuspendSynchronization() {
    List<TransactionSynchronization> suspendedSynchronizations =
        TransactionSynchronizationManager.getSynchronizations();
    for (TransactionSynchronization synchronization : suspendedSynchronizations) {
        synchronization.suspend();
    }
    TransactionSynchronizationManager.clearSynchronization();
    return suspendedSynchronizations;
}

有了挂起就必然有恢复的逻辑resume

protected final void resume(@Nullable Object transaction, @Nullable SuspendedResourcesHolder resourcesHolder)
    throws TransactionException {
	
    if (resourcesHolder != null) {
        Object suspendedResources = resourcesHolder.suspendedResources;
        if (suspendedResources != null) {
            // 子类实现具体如何恢复底层事务对象
            doResume(transaction, suspendedResources);
        }
        // 恢复同步器信息
        List<TransactionSynchronization> suspendedSynchronizations = resourcesHolder.suspendedSynchronizations;
        if (suspendedSynchronizations != null) {
            TransactionSynchronizationManager.setActualTransactionActive(resourcesHolder.wasActive);
            TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(resourcesHolder.isolationLevel);
            TransactionSynchronizationManager.setCurrentTransactionReadOnly(resourcesHolder.readOnly);
            TransactionSynchronizationManager.setCurrentTransactionName(resourcesHolder.name);
            doResumeSynchronization(suspendedSynchronizations);
        }
    }
}

private void doResumeSynchronization(List<TransactionSynchronization> suspendedSynchronizations) {
    TransactionSynchronizationManager.initSynchronization();
    for (TransactionSynchronization synchronization : suspendedSynchronizations) {
        synchronization.resume();
        TransactionSynchronizationManager.registerSynchronization(synchronization);
    }
}

提交事务

主要触发事件回调方法,具体的提交又子类实现

@Override
public final void commit(TransactionStatus status) throws TransactionException {
    if (status.isCompleted()) {
        throw new IllegalTransactionStateException("Transaction is already completed - do not call commit or rollback more than once per transaction");
    }

    DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
    if (defStatus.isLocalRollbackOnly()) {
        processRollback(defStatus, false);
        return;
    }

    if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
        processRollback(defStatus, true);
        return;
    }
	// 具体的提交逻辑
    processCommit(defStatus);
}

private void processCommit(DefaultTransactionStatus status) throws TransactionException {
    try {
        boolean beforeCompletionInvoked = false;

        try {
            // 处理回调事件,只有isNewSynchronization=true时才会真正触发回调事件
            boolean unexpectedRollback = false;
            prepareForCommit(status);
            triggerBeforeCommit(status);
            triggerBeforeCompletion(status);
            beforeCompletionInvoked = true;
	
            if (status.hasSavepoint()) {
                // 有保存点,那么就释放保存点
                unexpectedRollback = status.isGlobalRollbackOnly();
                status.releaseHeldSavepoint();
            } else if (status.isNewTransaction()) {
				// 是新建的事务
                unexpectedRollback = status.isGlobalRollbackOnly();
                
                // 这里子类去实现真正的如何提交
                doCommit(status);
            } else if (isFailEarlyOnGlobalRollbackOnly()) {
                unexpectedRollback = status.isGlobalRollbackOnly();
            }

            // Throw UnexpectedRollbackException if we have a global rollback-only
            // marker but still didn't get a corresponding exception from commit.
            if (unexpectedRollback) {
                throw new UnexpectedRollbackException("Transaction silently rolled back because it has been marked as rollback-only");
            }
        } catch (UnexpectedRollbackException ex) {
            // can only be caused by doCommit
            triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
            throw ex;
        } catch (TransactionException ex) {
            // can only be caused by doCommit
            if (isRollbackOnCommitFailure()) {
                doRollbackOnCommitException(status, ex);
            } else {
                triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
            }
            throw ex;
        } catch (RuntimeException | Error ex) {
            if (!beforeCompletionInvoked) {
                triggerBeforeCompletion(status);
            }
            doRollbackOnCommitException(status, ex);
            throw ex;
        }

        // Trigger afterCommit callbacks, with an exception thrown there
        // propagated to callers but the transaction still considered as committed.
        try {
            triggerAfterCommit(status);
        } finally {
            triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
        }

    } finally {
        cleanupAfterCompletion(status);
    }
}

执行提交的逻辑

  1. 当前事务存在保存点,那么说明当前是嵌套事务,直接将保存点释放即可。
  2. 当前事务是新建事务(status.isNewTransaction()=true)时,执行底层事务的提交操doCommit(),例如:当事务传播行为是REQUEST时,只有最外层方法提交事务时才会调用doCommit()执行底层事务提交。
  3. 提交事务方法中我们看到执行了很多的回调事件,这些都是模板方法,只有TransactionStatusisNewSynchronization=true时,才会执行回调方法。

回滚方法执行

private void processRollback(DefaultTransactionStatus status, boolean unexpected) {
    try {
        boolean unexpectedRollback = unexpected;

        try {
            triggerBeforeCompletion(status);
			// 如果有保存点,那么回滚到保存点
            if (status.hasSavepoint()) {
                status.rollbackToHeldSavepoint();
            } else if (status.isNewTransaction()) {
                
                // 子类实现具体的回滚逻辑
                doRollback(status);
            } else {
                // Participating in larger transaction
                if (status.hasTransaction()) {
                    if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
                        doSetRollbackOnly(status);
                    }
                }
                // Unexpected rollback only matters here if we're asked to fail early
                if (!isFailEarlyOnGlobalRollbackOnly()) {
                    unexpectedRollback = false;
                }
            }
        } catch (RuntimeException | Error ex) {
            triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
            throw ex;
        }

        triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);

        // Raise UnexpectedRollbackException if we had a global rollback-only marker
        if (unexpectedRollback) {
            throw new UnexpectedRollbackException("Transaction rolled back because it has been marked as rollback-only");
        }
    } finally {
        cleanupAfterCompletion(status);
    }
}

processRollback()处理回滚逻辑

  1. 如果当前存在保存点(说明是嵌入式事务),那么直接回滚到保存点。
  2. 如果当前是新建事务,那么执行具体底层事务的提交逻辑,交由子类实现doRollback()

接下来,我们继续看模板的具体实现,DataSourceTransactionManager就是一个具体的实现,其主要功能就是为抽象模板提供具体的事物创建,事物提交,事物回滚,以及具体的事物对象(模板类中,提供的事物Transaction是Object类型)

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值