1. 程式人生 > >spring技術內幕讀書筆記--事務處理

spring技術內幕讀書筆記--事務處理

事務模組類結構
這裡寫圖片描述

宣告式事務

宣告式事務處理大致分為以下幾個步驟
1)從配置檔案中讀取事務配置,並將事務元資料轉化為spring內部元資料物件。
涉及類:TransactionAttributeSourceAdvisor(此通知器類會將事務處理的屬性資訊抽象到TransactionAttribute物件中)
2)將事務處理物件與當前執行緒繫結,通過TransactionInfo和TransactionStatus這兩個資料物件進行事務處理過程中相關執行場景的記錄和傳遞。
3)PlatformTransactionManager對事務的具體實現。

  • 宣告式事務處理啟動

宣告式事務配置

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>

<bean id="toBeTestService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
>
<property name="target"> <!--被代理目標類--> <bean class="com.test.m.service.ToBeTestService"/> </property> <property name="transactionManager" ref="transactionManager"/> <property name="transactionAttributes"> <props> <prop
key="insert*">
PROPAGATION_REQUIRED</prop> <prop key="update*">PROPAGATION_REQUIRED</prop> <prop key="select*">PROPAGATION_REQUIRES_NEW</prop> <prop key="*">PROPAGATION_REQUIRED,readOnly</prop> </props> </property> </bean>

transactionAttributes中的屬性為事務處理的攔截規則,由NameMatchTransactionAttributeSource實現,規則會被封裝到一個map中
這裡寫圖片描述
如:key為insert*,value為PROPAGATION_REQUIRED

TransactionProxyFactoryBean是個FactoryBean,是生成具有事務特性代理類的入口。
TransactionProxyFactoryBean繼承關係

這裡寫圖片描述

先大致看一下事務處理代理物件的建立流程

這裡寫圖片描述

下面來具體分析

TransactionProxyFactoryBean實現了InitializingBean與FactoryBean,所以TransactionProxyFactoryBean的IoC容器初始化方法為afterPropertiesSet方法。

@Override
public void afterPropertiesSet() {
    if (this.target == null) {
        throw new IllegalArgumentException("Property 'target' is required");
    }
    if (this.target instanceof String) {
        throw new IllegalArgumentException("'target' needs to be a bean reference, not a bean name as value");
    }
    if (this.proxyClassLoader == null) {
        this.proxyClassLoader = ClassUtils.getDefaultClassLoader();
    }
    //建立事務代理物件
    ProxyFactory proxyFactory = new ProxyFactory();
    //設定自定義前置攔截器
    if (this.preInterceptors != null) {
        for (Object interceptor : this.preInterceptors) {
            proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor));
        }
    }
    //建立事務處理的AOP通知器
    proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(createMainInterceptor()));
    //設定自定義後置攔截器
    if (this.postInterceptors != null) {
        for (Object interceptor : this.postInterceptors) {
            proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor));
        }
    }
    proxyFactory.copyFrom(this);
    //建立AOP的目標源
    TargetSource targetSource = createTargetSource(this.target);
    proxyFactory.setTargetSource(targetSource);
    if (this.proxyInterfaces != null) {
        proxyFactory.setInterfaces(this.proxyInterfaces);
    }
    else if (!isProxyTargetClass()) {
        // Rely on AOP infrastructure to tell us what interfaces to proxy.
        proxyFactory.setInterfaces(
                ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass(), this.proxyClassLoader));
    }
    postProcessProxyFactory(proxyFactory);
    //建立事務代理物件
    this.proxy = proxyFactory.getProxy(this.proxyClassLoader);
}

/**
 * 建立事務處理的AOP通知器
 */
protected Object createMainInterceptor() {
    this.transactionInterceptor.afterPropertiesSet();
    if (this.pointcut != null) {
        //使用預設通知器,並配置事務處理攔截器
        return new DefaultPointcutAdvisor(this.pointcut, this.transactionInterceptor);
    }
    else {
        //若沒有配置切點,使用TransactionAttributeSourceAdvisor通知器,並配置事務處理攔截器
        return new TransactionAttributeSourceAdvisor(this.transactionInterceptor);
    }
}
  • 事務處理通知器初始化

這裡通過TransactionAttributeSourceAdvisor通知器來進行分析
Advisor需要有兩個元素,切點(Pointcut)和切面(Interceptor)這裡的切點為TransactionAttributeSourceAdvisor類中宣告的TransactionAttributeSourcePointcut,並通過TransactionAttributeSourcePointcut內部的matches方法來做目標方法是否攔截的規則匹配

@Override
public boolean matches(Method method, Class<?> targetClass) {
    if (TransactionalProxy.class.isAssignableFrom(targetClass)) {
        return false;
    }
    //從TransactionInterceptor中獲取TransactionAttributeSource(宣告中配置的攔截規則)物件,具體實現為
    //NameMatchTransactionAttributeSource實現類
    TransactionAttributeSource tas = getTransactionAttributeSource();
    return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}

具體的匹配規則實現(NameMatchTransactionAttributeSource.getTransactionAttribute)

/**
 * 根據方法名進行正則匹配看是否有對應的事務屬性物件(主要是一些配置的隔離級別,readonly等等),若呢個匹配
 * 到具體的TransactionAttribute物件,說明TransactionInterceptor做好了對呼叫目標的方法新增事務處理
 * 的準備
 */
@Override
public TransactionAttribute getTransactionAttribute(Method method, Class<?> targetClass) {
    if (!ClassUtils.isUserLevelMethod(method)) {
        return null;
    }
    // Look for direct name match.
    String methodName = method.getName();
    TransactionAttribute attr = this.nameMap.get(methodName);
    if (attr == null) {
        // Look for most specific name match.
        String bestNameMatch = null;
        for (String mappedName : this.nameMap.keySet()) {
            if (isMatch(methodName, mappedName) &&
                    (bestNameMatch == null || bestNameMatch.length() <= mappedName.length())) {
                attr = this.nameMap.get(mappedName);
                bestNameMatch = mappedName;
            }
        }
    }
    return attr;
}
  • 事務攔截器的具體實現

由於事務AOP是通過CglibAopProxy實現的,大概說明下呼叫流程
這裡寫圖片描述

所以我們看TransactionInterceptor中的invoke方法

@Override
public Object invoke(final MethodInvocation invocation) throws Throwable {
    Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
    return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
        @Override
        public Object proceedWithInvocation() throws Throwable {
            return invocation.proceed();
        }
    });
}
protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
        throws Throwable {
    // 通過TransactionAttributeSource物件取得事務的屬性配置
    final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
    // 根據TransactionProxyFactoryBean的配置資訊獲得具體的事務處理器
    final PlatformTransactionManager tm = determineTransactionManager(txAttr);
    final String joinpointIdentification = methodIdentification(method, targetClass);
    // 不同型別的PlatformTransactionManager呼叫方式不同,CallbackPreferringPlatformTransactionManager需要回調函式來實現事務流程,而我們常用的DataSourceTransactionManager就不是CallbackPreferringPlatformTransactionManager
    if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
        // 建立事務物件,其中儲存了事務狀態物件
        // TransactionInfo是一個事務物件,物件中包含事務的所有屬性,包括PlatformTransactionManager、TransactionAttribute、TransactionStatus
        // ⚠️事務的管理都是通過TransactionInfo物件來完成,它封裝了事務物件和事務處理的狀態資訊
        TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
        Object retVal = null;
        try {
            // 進行攔截器和目標方法的呼叫
            retVal = invocation.proceedWithInvocation();
        }
        catch (Throwable ex) {
            // 回滾
            completeTransactionAfterThrowing(txInfo, ex);
            throw ex;
        }
        finally {
            cleanupTransactionInfo(txInfo);
        }
        // 提交
        commitTransactionAfterReturning(txInfo);
        return retVal;
    }
    else {
        // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
        try {
            Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr,
                    new TransactionCallback<Object>() {
                        @Override
                        public Object doInTransaction(TransactionStatus status) {
                            TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
                            try {
                                return invocation.proceedWithInvocation();
                            }
                            catch (Throwable ex) {
                                if (txAttr.rollbackOn(ex)) {
                                    // A RuntimeException: will lead to a rollback.
                                    if (ex instanceof RuntimeException) {
                                        throw (RuntimeException) ex;
                                    }
                                    else {
                                        throw new ThrowableHolderException(ex);
                                    }
                                }
                                else {
                                    // A normal return value: will lead to a commit.
                                    return new ThrowableHolder(ex);
                                }
                            }
                            finally {
                                cleanupTransactionInfo(txInfo);
                            }
                        }
                    });
            // Check result: It might indicate a Throwable to rethrow.
            if (result instanceof ThrowableHolder) {
                throw ((ThrowableHolder) result).getThrowable();
            }
            else {
                return result;
            }
        }
        catch (ThrowableHolderException ex) {
            throw ex.getCause();
        }
    }
}

流程圖
這裡寫圖片描述
1)讀取事務方法的事務屬性配置
2)獲取PlatformTransactionManager事務處理器的具體實現
3)決定是否建立新的事務(後面會具體分析)
4)對攔截器和目標物件進行呼叫
5)根據執行進行commit或rollback

  • 事務的建立

程式設計式建立事務

        DataSourceTransactionManager manager = new DataSourceTransactionManager();
        TransactionDefinition td = new DefaultTransactionDefinition();
        TransactionStatus transaction = manager.getTransaction(td);
        try{
            //todo
        }catch (Exception e){
            manager.rollback(transaction);
        }
        manager.commit(transaction);

事務建立流程圖
這裡寫圖片描述

大致過程一句話:通過DataSourceTransactionManager建立一個TransactionStatus,並將TransactionStatus設定到當前的TransactionInfo中,同時將此TransactionInfo與當前執行緒繫結。

下面我們來分析DataSourceTransactionManager.getTransaction方法

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

    // 獲取ConnectionHolder資料來源連線物件
    Object transaction = doGetTransaction();
    boolean debugEnabled = logger.isDebugEnabled();
    if (definition == null) {
        definition = new DefaultTransactionDefinition();
    }
    // 是否是巢狀事務,若是,則根據事務的傳播屬性來處理事務的產生
    if (isExistingTransaction(transaction)) {
        return handleExistingTransaction(definition, transaction, debugEnabled);
    }
    // 檢查事務屬性中timeout的設定是否合理
    if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
        throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
    }
    // 根據事務的傳播屬性進行相應的處理
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
        throw new IllegalTransactionStateException(
                "No existing transaction found for transaction marked with propagation 'mandatory'");
    }
    else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
            definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
            definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
        SuspendedResourcesHolder suspendedResources = suspend(null);
        if (debugEnabled) {
            logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);
        }
        try {
            boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
            // 建立TransactionStatus
            DefaultTransactionStatus status = newTransactionStatus(
                    definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
            // 開啟事務(呼叫connect物件的setAutoCommit(false)和setTransactionActive(true))
            doBegin(transaction, definition);
            // 初始化當前執行緒的threadlocal物件
            prepareSynchronization(status, definition);
            return status;
        }
        catch (RuntimeException ex) {
            resume(null, suspendedResources);
            throw ex;
        }
        catch (Error err) {
            resume(null, suspendedResources);
            throw err;
        }
    }
    else {
        // Create "empty" transaction: no actual transaction, but potentially synchronization.
        if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
            logger.warn("Custom isolation level specified but no actual transaction initiated; " +
                    "isolation level will effectively be ignored: " + definition);
        }
        boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
        return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
    }
}

建立新事物比較好理解,根據事務屬性的配置建立事務物件並儲存到TransactionStatus中,並將事務屬性資訊與當前執行緒繫結。
對於巢狀式事務,需要關注下AbstractPlatformTransactionManager.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) {
        if (debugEnabled) {
            logger.debug("Suspending current transaction");
        }
        // 將當前事務掛起
        Object suspendedResources = suspend(transaction);
        boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
        // 這裡transaction為null,newTransaction為false,說明事務方法不需要放在事務環境中執行,會將之前的事務資訊儲存在當前的TransactionStatus物件中
        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 {
            boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
            DefaultTransactionStatus status = newTransactionStatus(
                    definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
            doBegin(transaction, definition);
            prepareSynchronization(status, definition);
            return status;
        }
        catch (RuntimeException beginEx) {
            resumeAfterBeginException(transaction, suspendedResources, beginEx);
            throw beginEx;
        }
        catch (Error beginErr) {
            resumeAfterBeginException(transaction, suspendedResources, beginErr);
            throw beginErr;
        }
    }
    // 巢狀事務的建立
    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() + "]");
        }
        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.
            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.
            boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
            DefaultTransactionStatus status = newTransactionStatus(
                    definition, transaction, true, newSynchronization, debugEnabled, null);
            doBegin(transaction, definition);
            prepareSynchronization(status, definition);
            return status;
        }
    }
    // 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");
            }
        }
    }
    boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
    // 第三個引數false代表當前事務方法沒有使用新事務
    return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
}
  • 事務的掛起

事務的掛起原理機制大概理解為
1)獲取上一次事務的資料來源物件封裝並返回SuspendedResourcesHolder物件
2)呼叫doBegin方法建立新的資料來源連線物件與新的事務資訊物件
2)將SuspendedResourcesHolder設定到新的TransactionStatus中

protected final SuspendedResourcesHolder suspend(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 ex) {
            // doSuspend failed - original transaction is still active...
            doResumeSynchronization(suspendedSynchronizations);
            throw ex;
        }
        catch (Error err) {
            // doSuspend failed - original transaction is still active...
            doResumeSynchronization(suspendedSynchronizations);
            throw err;
        }
    }
    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;
    }
}
@Override
protected Object doSuspend(Object transaction) {
    DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
    txObject.setConnectionHolder(null);
    // 獲取上一次事務的資料來源連線物件,並將其從當前ThreadLocal中移除
    ConnectionHolder conHolder = (ConnectionHolder)
            TransactionSynchronizationManager.unbindResource(this.dataSource);
    return conHolder;
}
  • 事務的提交

直接看事務提交的流程AbstractPlatformTransactionManager.processCommit

private void processCommit(DefaultTransactionStatus status) throws TransactionException {
    try {
        boolean beforeCompletionInvoked = false;
        try {
            // 事務提交的準備工作,如果集成了mybatis,事務的真正提交在此方法中完成,spring的事務物件僅僅做事務狀態的記錄
            prepareForCommit(status);
            triggerBeforeCommit(status);
            triggerBeforeCompletion(status);
            beforeCompletionInvoked = true;
            boolean globalRollbackOnly = false;
            if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {
                globalRollbackOnly = status.isGlobalRollbackOnly();
            }
            // 巢狀事務的處理
            if (status.hasSavepoint()) {
                if (status.isDebug()) {
                    logger.debug("Releasing transaction savepoint");
                }
                status.releaseHeldSavepoint();
            }
            // 是否是一個新事物
            else if (status.isNewTransaction()) {
                if (status.isDebug()) {
                    logger.debug("Initiating transaction commit");
                }
                // 具體的事務提交由具體的事務處理器來完成
                doCommit(status);
            }
            // Throw UnexpectedRollbackException if we have a global rollback-only
            // marker but still didn't get a corresponding exception from commit.
            if (globalRollbackOnly) {
                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 ex) {
            if (!beforeCompletionInvoked) {
                triggerBeforeCompletion(status);
            }
            doRollbackOnCommitException(status, ex);
            throw ex;
        }
        catch (Error err) {
            if (!beforeCompletionInvoked) {
                triggerBeforeCompletion(status);
            }
            doRollbackOnCommitException(status, err);
            throw err;
        }
        // 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);
    }
}

⚠️:如果是mybatis整合模式下,spring不負責具體的提交回滾操作,只是做事務狀態的記錄!!具體可以參考mybatis原始碼org.mybatis.spring.SqlSessionUtils.SqlSessionSynchronization類

  • 事務回滾

直接看程式碼吧

private void processRollback(DefaultTransactionStatus status) {
    try {
        try {
            // 若集成了mybatis,真正資料來源的回滾操作發生在這裡
            triggerBeforeCompletion(status);
            if (status.hasSavepoint()) {
                if (status.isDebug()) {
                    logger.debug("Rolling back transaction to savepoint");
                }
                status.rollbackToHeldSavepoint();
            }
            else if (status.isNewTransaction()) {
                if (status.isDebug()) {
                    logger.debug("Initiating transaction rollback");
                }
                doRollback(status);
            }
            else if (status.hasTransaction()) {
                if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
                    if (status.isDebug()) {
                        logger.debug("Participating transaction failed - marking existing transaction as rollback-only");
                    }
                    doSetRollbackOnly(status);
                }
                else {
                    if (status.isDebug()) {
                        logger.debug("Participating transaction failed - letting transaction originator decide on rollback");
                    }
                }
            }
            else {
                logger.debug("Should roll back transaction but cannot - no transaction available");
            }
        }
        catch (RuntimeException ex) {
            triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
            throw ex;
        }
        catch (Error err) {
            triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
            throw err;
        }
        triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
    }
    finally {
        cleanupAfterCompletion(status);
    }
}

PlatformTransactionManager具體實現

事務處理最重要的4個方法
1)doGetTrancation:建立資料來源物件並封裝返回事務物件
2)doBegin:開啟事務
3)doCommit:提交
4)doRollback:回滾
都是由在TransactionProxyFactoryBean中配置的具體的TransactionManager實現

這裡寫圖片描述

大致看下DataSourceTransactionManager和HibernateTransactionManager的執行流程,原始碼比較簡單,暫不做分析了

這裡寫圖片描述

這裡寫圖片描述