最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot事務(wù)源碼從注解到數(shù)據(jù)庫的全解析

 更新時(shí)間:2026年03月24日 09:44:38   作者:Bug博物館  
本文深度解析SpringBoot事務(wù)源碼:從@Transactional注解觸發(fā)AOP代理,到TransactionInterceptor攔截,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧

各位Java大俠,上回我們聊了SpringBoot事務(wù)的“表面功夫”,今天咱們來個(gè)深度解剖,看看當(dāng)你瀟灑地寫下@Transactional時(shí),SpringBoot在背后到底干了多少“臟活累活”。準(zhǔn)備好你的IDE,咱們一起開啟源碼之旅!??

第一章:@Transactional的“前世今生”——注解解析全流程 ??

1.1 注解的“出生證明”

當(dāng)你寫@Transactional時(shí),Spring是怎么知道要處理它的?

關(guān)鍵類TransactionInterceptorAnnotationTransactionAttributeSource、BeanFactoryTransactionAttributeSourceAdvisor

// 1. 首先,Spring啟動(dòng)時(shí),@EnableTransactionManagement注解開啟事務(wù)支持
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
    // 代理模式:CGLIB 還是 JDK動(dòng)態(tài)代理?
    AdviceMode mode() default AdviceMode.PROXY;
    // 代理順序
    int order() default Ordered.LOWEST_PRECEDENCE;
}

執(zhí)行流程

// 簡化版調(diào)用鏈
1. 容器啟動(dòng) → @EnableTransactionManagement生效
2. → 注冊(cè) InfrastructureAdvisorAutoProxyCreator(AOP代理創(chuàng)建器)
3. → 掃描所有Bean,找@Transactional注解的方法
4. → 創(chuàng)建代理對(duì)象,將TransactionInterceptor作為增強(qiáng)
5. → 調(diào)用代理方法時(shí),進(jìn)入TransactionInterceptor.invoke()

1.2 TransactionInterceptor的核心invoke()方法

這是事務(wù)的總?cè)肟?/strong>,讓我們看看它的真面目:

// org.springframework.transaction.interceptor.TransactionInterceptor
public class TransactionInterceptor extends TransactionAspectSupport 
    implements MethodInterceptor, Serializable {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        // 獲取目標(biāo)類
        Class<?> targetClass = (invocation.getThis() != null ? 
            AopUtils.getTargetClass(invocation.getThis()) : null);
        // 關(guān)鍵!調(diào)用父類的invokeWithinTransaction方法
        return invokeWithinTransaction(
            invocation.getMethod(),  // 被調(diào)用的方法
            targetClass,             // 目標(biāo)類
            invocation::proceed      // 實(shí)際要執(zhí)行的業(yè)務(wù)方法
        );
    }
}

第二章:invokeWithinTransaction——事務(wù)的“心臟” ??

這才是真正的事務(wù)處理核心,代碼在父類TransactionAspectSupport中:

// org.springframework.transaction.interceptor.TransactionAspectSupport
protected Object invokeWithinTransaction(Method method, 
                                        @Nullable Class<?> targetClass,
                                        final InvocationCallback invocation) throws Throwable {
    // 1?? 獲取事務(wù)屬性(@Transactional注解的配置)
    TransactionAttributeSource tas = getTransactionAttributeSource();
    final TransactionAttribute txAttr = (tas != null ? 
        tas.getTransactionAttribute(method, targetClass) : null);
    // 2?? 確定事務(wù)管理器
    final PlatformTransactionManager tm = determineTransactionManager(txAttr);
    // 3?? 構(gòu)造方法標(biāo)識(shí)(用于日志和監(jiān)控)
    final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
    // 4?? 聲明式事務(wù)處理
    if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
        // ?? 關(guān)鍵!獲取事務(wù)狀態(tài)
        TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
        Object retVal = null;
        try {
            // 5?? 執(zhí)行真正的業(yè)務(wù)邏輯
            retVal = invocation.proceedWithInvocation();
        }
        catch (Throwable ex) {
            // 6?? 異常處理:回滾或提交
            completeTransactionAfterThrowing(txInfo, ex);
            throw ex;
        }
        finally {
            // 7?? 清理線程綁定的資源
            cleanupTransactionInfo(txInfo);
        }
        // 8?? 提交事務(wù)
        commitTransactionAfterReturning(txInfo);
        return retVal;
    }
    else {
        // 編程式事務(wù)處理(略)
    }
}

第三章:createTransactionIfNecessary——事務(wù)的“誕生” ??

這個(gè)方法決定了是否創(chuàng)建新事務(wù)、如何傳播事務(wù)

// TransactionAspectSupport.createTransactionIfNecessary
protected TransactionInfo createTransactionIfNecessary(
        @Nullable PlatformTransactionManager tm,
        @Nullable TransactionAttribute txAttr, 
        final String joinpointIdentification) {
    // 如果transaction屬性為空,則創(chuàng)建一個(gè)空事務(wù)
    if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
        // 1. 獲取現(xiàn)有事務(wù)(可能為null)
        TransactionStatus status = null;
        if (txAttr != null) {
            if (tm != null) {
                // ?? 關(guān)鍵!調(diào)用事務(wù)管理器的getTransaction方法
                status = tm.getTransaction(txAttr);
            }
        }
        // 2. 準(zhǔn)備事務(wù)信息
        return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
    }
    // ...
}

3.1 tm.getTransaction()——傳播行為的實(shí)現(xiàn)

這是各種傳播行為的實(shí)現(xiàn)核心,在AbstractPlatformTransactionManager中:

// AbstractPlatformTransactionManager.getTransaction
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) 
        throws TransactionException {
    // 1. 獲取事務(wù)定義(沒有則用默認(rèn)值)
    TransactionDefinition def = (definition != null ? definition : 
        TransactionDefinition.withDefaults());
    // 2. ?? 獲取現(xiàn)有事務(wù)(檢查當(dāng)前線程是否已有事務(wù))
    Object transaction = doGetTransaction();
    // 3. 如果當(dāng)前已存在事務(wù)
    if (isExistingTransaction(transaction)) {
        // ?? 處理嵌套事務(wù)的情況
        return handleExistingTransaction(def, transaction, debugEnabled);
    }
    // 4. 檢查超時(shí)設(shè)置
    if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
        throw new InvalidTimeoutException(...);
    }
    // 5. 當(dāng)前沒有事務(wù),但需要事務(wù)(REQUIRED, REQUIRES_NEW等)
    if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
        throw new IllegalTransactionStateException(...);
    }
    else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
             def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
             def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
        // ?? 關(guān)鍵!掛起null事務(wù)(因?yàn)楫?dāng)前沒有事務(wù))
        SuspendedResourcesHolder suspendedResources = suspend(null);
        try {
            // 6. 開始新事務(wù)
            return startTransaction(def, transaction, debugEnabled, suspendedResources);
        }
        catch (RuntimeException | Error ex) {
            resume(null, suspendedResources);
            throw ex;
        }
    }
    else {
        // 7. 當(dāng)前不需要事務(wù)(PROPAGATION_SUPPORTS等)
        boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
        return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
    }
}

3.2 傳播行為的核心:handleExistingTransaction()

讓我們看看不同傳播行為在已有事務(wù)時(shí)的處理

// AbstractPlatformTransactionManager.handleExistingTransaction
private TransactionStatus handleExistingTransaction(
        TransactionDefinition definition, Object transaction, boolean debugEnabled)
        throws TransactionException {
    // 1. NEVER:不能有事務(wù),有就拋異常
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
        throw new IllegalTransactionStateException(...);
    }
    // 2. NOT_SUPPORTED:不支持事務(wù),掛起當(dāng)前事務(wù)
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
        Object suspendedResources = suspend(transaction);
        boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
        return prepareTransactionStatus(
            definition, null, false, newSynchronization, debugEnabled, suspendedResources);
    }
    // 3. REQUIRES_NEW:掛起當(dāng)前事務(wù),創(chuàng)建新事務(wù)
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
        // 掛起當(dāng)前事務(wù)
        SuspendedResourcesHolder suspendedResources = suspend(transaction);
        try {
            // 開始新事務(wù)
            return startTransaction(definition, transaction, debugEnabled, suspendedResources);
        }
        catch (RuntimeException | Error beginEx) {
            resumeAfterBeginException(transaction, suspendedResources, beginEx);
            throw beginEx;
        }
    }
    // 4. NESTED:嵌套事務(wù)
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
        if (!isNestedTransactionAllowed()) {
            throw new NestedTransactionNotSupportedException(...);
        }
        // 使用保存點(diǎn)(Savepoint)實(shí)現(xiàn)
        if (useSavepointForNestedTransaction()) {
            // 創(chuàng)建保存點(diǎn)
            DefaultTransactionStatus status = prepareTransactionStatus(
                definition, transaction, false, false, debugEnabled, null);
            status.createAndHoldSavepoint();
            return status;
        }
        else {
            // 有些數(shù)據(jù)庫不支持保存點(diǎn),只能開啟新事務(wù)
            return startTransaction(definition, transaction, debugEnabled, null);
        }
    }
    // 5. 其他(REQUIRED, SUPPORTS, MANDATORY):加入當(dāng)前事務(wù)
    if (isValidateExistingTransaction()) {
        // 驗(yàn)證隔離級(jí)別、只讀等設(shè)置是否匹配
    }
    boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
    return prepareTransactionStatus(
        definition, transaction, false, newSynchronization, debugEnabled, null);
}

第四章:startTransaction——開啟事務(wù)的“魔法” ??

真正的事務(wù)開啟在這里:

// DataSourceTransactionManager(具體實(shí)現(xiàn))
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
    DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
    Connection con = null;
    try {
        // 1. 如果還沒有連接,從數(shù)據(jù)源獲取
        if (!txObject.hasConnectionHolder() ||
            txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
            Connection newCon = obtainDataSource().getConnection();
            txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
        }
        // 2. 設(shè)置連接屬性
        txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
        con = txObject.getConnectionHolder().getConnection();
        // 3. ?? 關(guān)鍵!設(shè)置隔離級(jí)別
        Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(
            con, definition);
        txObject.setPreviousIsolationLevel(previousIsolationLevel);
        // 4. ?? 關(guān)鍵!關(guān)閉自動(dòng)提交
        if (con.getAutoCommit()) {
            txObject.setMustRestoreAutoCommit(true);
            con.setAutoCommit(false);  // 就是這一行!
        }
        // 5. 準(zhǔn)備事務(wù)連接
        prepareTransactionalConnection(con, definition);
        // 6. 設(shè)置事務(wù)狀態(tài)
        txObject.getConnectionHolder().setTransactionActive(true);
        // 7. 設(shè)置超時(shí)
        int timeout = determineTimeout(definition);
        if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
            txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
        }
        // 8. 綁定到當(dāng)前線程
        if (txObject.isNewConnectionHolder()) {
            TransactionSynchronizationManager.bindResource(
                obtainDataSource(), txObject.getConnectionHolder());
        }
    } catch (Throwable ex) {
        // 異常處理
        DataSourceUtils.releaseConnection(con, obtainDataSource());
        throw new CannotCreateTransactionException(...);
    }
}

看到第4步的con.setAutoCommit(false)了嗎?這就是Spring事務(wù)的基石!沒有它,每個(gè)SQL都會(huì)自動(dòng)提交,就無法回滾了。

第五章:commitTransactionAfterReturning——提交的“藝術(shù)” ??

業(yè)務(wù)方法執(zhí)行成功后,提交事務(wù):

// TransactionAspectSupport.commitTransactionAfterReturning
protected void commitTransactionAfterReturning(@Nullable TransactionInfo txInfo) {
    if (txInfo != null && txInfo.getTransactionStatus() != null) {
        txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
    }
}
// AbstractPlatformTransactionManager.commit
public final void commit(TransactionStatus status) throws TransactionException {
    // 1. 檢查事務(wù)是否已完成
    if (status.isCompleted()) {
        throw new IllegalTransactionStateException(...);
    }
    DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
    // 2. 如果標(biāo)記了回滾,則回滾
    if (defStatus.isLocalRollbackOnly()) {
        processRollback(defStatus, false);
        return;
    }
    // 3. 檢查是否需要全局回滾
    if (!shouldCommitOnGlobalRollbackOnly() && 
        defStatus.isGlobalRollbackOnly()) {
        processRollback(defStatus, true);
        return;
    }
    // 4. ?? 真正的提交
    processCommit(defStatus);
}

5.1 processCommit——真正的提交

// AbstractPlatformTransactionManager.processCommit
private void processCommit(DefaultTransactionStatus status) throws TransactionException {
    try {
        boolean beforeCompletionInvoked = false;
        try {
            // 1. 觸發(fā)提交前回調(diào)
            prepareForCommit(status);
            triggerBeforeCommit(status);
            triggerBeforeCompletion(status);
            beforeCompletionInvoked = true;
            // 2. 如果有保存點(diǎn)(嵌套事務(wù))
            if (status.hasSavepoint()) {
                status.releaseHeldSavepoint();  // 釋放保存點(diǎn),但不提交
                return;
            }
            // 3. 如果是新事務(wù),才真正提交
            if (status.isNewTransaction()) {
                doCommit(status);  // ?? 調(diào)用數(shù)據(jù)源提交
            }
            // 4. 如果是全局回滾
            else if (status.isGlobalRollbackOnly()) {
                unexpectedRollback = true;
            }
        }
        catch (UnexpectedRollbackException ex) {
            // 異常處理
        }
        finally {
            // 5. 清理資源
            cleanupAfterCompletion(status);
        }
    }
    finally {
        // ...
    }
}

5.2 DataSourceTransactionManager.doCommit()

// DataSourceTransactionManager.doCommit
@Override
protected void doCommit(DefaultTransactionStatus status) {
    DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
    Connection con = txObject.getConnectionHolder().getConnection();
    try {
        con.commit();  // ?? JDBC提交!
    } catch (SQLException ex) {
        throw new TransactionSystemException("Could not commit JDBC transaction", ex);
    }
}

第六章:completeTransactionAfterThrowing——回滾的“學(xué)問” ??

業(yè)務(wù)方法拋出異常時(shí),決定是否回滾:

// TransactionAspectSupport.completeTransactionAfterThrowing
protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {
    // 1. 必須要有事務(wù)才需要回滾
    if (txInfo != null && txInfo.getTransactionStatus() != null) {
        // 2. ?? 關(guān)鍵!判斷是否應(yīng)該回滾
        if (txInfo.transactionAttribute != null && 
            txInfo.transactionAttribute.rollbackOn(ex)) {
            try {
                // 3. 執(zhí)行回滾
                txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
            }
            catch (TransactionSystemException ex2) {
                ex2.initApplicationException(ex);
                throw ex2;
            }
        }
        else {
            // 4. 不應(yīng)該回滾,則提交
            try {
                txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
            }
            catch (TransactionSystemException ex2) {
                ex2.initApplicationException(ex);
                throw ex2;
            }
        }
    }
}

6.1 rollbackOn()——回滾判斷邏輯

// RuleBasedTransactionAttribute.rollbackOn
@Override
public boolean rollbackOn(Throwable ex) {
    // 1. 遍歷所有回滾規(guī)則
    for (RollbackRuleAttribute rule : this.rollbackRules) {
        // 2. 檢查異常是否匹配
        if (rule.getDepth(ex) >= 0) {
            return true;  // 匹配,需要回滾
        }
    }
    // 3. 默認(rèn):RuntimeException和Error回滾,CheckedException不?
    return (ex instanceof RuntimeException || ex instanceof Error);
}

這就是為什么默認(rèn)情況下,IOException等Checked Exception不回滾的原因!

第七章:ThreadLocal的妙用——事務(wù)資源綁定 ??

Spring如何保證同一個(gè)線程內(nèi),多個(gè)DAO操作用同一個(gè)連接?

核心類TransactionSynchronizationManager

// 內(nèi)部使用ThreadLocal存儲(chǔ)資源
public abstract class TransactionSynchronizationManager {
    private static final ThreadLocal<Map<Object, Object>> resources = 
        new NamedThreadLocal<>("Transactional resources");
    private static final ThreadLocal<Set<TransactionSynchronization>> synchronizations = 
        new NamedThreadLocal<>("Transaction synchronizations");
    private static final ThreadLocal<String> currentTransactionName = 
        new NamedThreadLocal<>("Current transaction name");
    private static final ThreadLocal<Boolean> currentTransactionReadOnly = 
        new NamedThreadLocal<>("Current transaction read-only status");
    private static final ThreadLocal<Integer> currentTransactionIsolationLevel = 
        new NamedThreadLocal<>("Current transaction isolation level");
    private static final ThreadLocal<Boolean> actualTransactionActive = 
        new NamedThreadLocal<>("Actual transaction active");
    // 綁定資源到當(dāng)前線程
    public static void bindResource(Object key, Object value) throws IllegalStateException {
        Map<Object, Object> map = resources.get();
        if (map == null) {
            map = new HashMap<>();
            resources.set(map);
        }
        map.put(key, value);
    }
    // 從當(dāng)前線程獲取資源
    public static Object getResource(Object key) {
        Map<Object, Object> map = resources.get();
        if (map == null) {
            return null;
        }
        return map.get(key);
    }
}

執(zhí)行流程

// 1. 事務(wù)開始時(shí)
Connection con = dataSource.getConnection();
TransactionSynchronizationManager.bindResource(dataSource, con);
// 2. DAO操作獲取連接時(shí)
public static Connection getConnection(DataSource dataSource) throws CannotGetJdbcConnectionException {
    // 先嘗試從ThreadLocal獲取
    ConnectionHolder conHolder = (ConnectionHolder) 
        TransactionSynchronizationManager.getResource(dataSource);
    if (conHolder != null) {
        return conHolder.getConnection();  // ? 返回事務(wù)連接
    }
    // 沒有事務(wù),新建連接
    return dataSource.getConnection();
}
// 3. 事務(wù)結(jié)束時(shí)
TransactionSynchronizationManager.unbindResource(dataSource);

第八章:自調(diào)用失效的“終極揭秘” ??

現(xiàn)在你明白為什么自調(diào)用事務(wù)不生效了嗎?

@Service
public class UserService {
    public void outerMethod() {
        // 直接調(diào)用內(nèi)部方法
        this.innerMethod();  // ? 事務(wù)不生效!
    }
    @Transactional
    public void innerMethod() {
        // 業(yè)務(wù)邏輯
    }
}

原因

  1. Spring事務(wù)基于AOP代理
  2. 只有通過代理對(duì)象調(diào)用,才會(huì)被TransactionInterceptor攔截
  3. this.innerMethod()目標(biāo)對(duì)象內(nèi)部調(diào)用,不會(huì)經(jīng)過代理
  4. 因此TransactionInterceptor.invoke()不會(huì)執(zhí)行

圖解

正常調(diào)用:Controller → 代理對(duì)象 → TransactionInterceptor → 目標(biāo)對(duì)象
自調(diào)用:目標(biāo)對(duì)象 → 目標(biāo)對(duì)象(繞過了代理和攔截器?。?/pre>

第九章:調(diào)試技巧——親眼看看事務(wù)流轉(zhuǎn) ??

9.1 開啟調(diào)試日志

# application.yml
logging:
  level:
    org.springframework.transaction: DEBUG
    org.springframework.jdbc.datasource.DataSourceTransactionManager: DEBUG
    org.springframework.orm.jpa: DEBUG

9.2 觀察日志輸出

DEBUG o.s.j.d.DataSourceTransactionManager: Creating new transaction with name [com.example.UserService.saveUser]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
DEBUG o.s.j.d.DataSourceTransactionManager: Acquired Connection [conn-id] for JDBC transaction
DEBUG o.s.j.d.DataSourceTransactionManager: Switching JDBC Connection [conn-id] to manual commit
DEBUG o.s.j.d.DataSourceTransactionManager: Initiating transaction commit
DEBUG o.s.j.d.DataSourceTransactionManager: Committing JDBC transaction on Connection [conn-id]
DEBUG o.s.j.d.DataSourceTransactionManager: Releasing JDBC Connection [conn-id] after transaction

9.3 在關(guān)鍵方法打斷點(diǎn)

  1. TransactionInterceptor.invoke()
  2. TransactionAspectSupport.invokeWithinTransaction()
  3. AbstractPlatformTransactionManager.getTransaction()
  4. DataSourceTransactionManager.doBegin()
  5. DataSourceTransactionManager.doCommit()/doRollback()

第十章:手寫一個(gè)簡化版事務(wù)管理器(理解原理) ???

理解了原理,讓我們手寫一個(gè)極簡版:

// 1. 事務(wù)管理器
public class SimpleTransactionManager {
    private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<>();
    private static ThreadLocal<Boolean> transactionActive = ThreadLocal.withInitial(() -> false);
    public static void begin() throws SQLException {
        if (transactionActive.get()) {
            return;  // 已存在事務(wù),支持傳播
        }
        Connection conn = DataSourceUtils.getConnection();
        conn.setAutoCommit(false);  // 關(guān)鍵!
        connectionHolder.set(conn);
        transactionActive.set(true);
    }
    public static void commit() throws SQLException {
        if (!transactionActive.get()) {
            return;
        }
        Connection conn = connectionHolder.get();
        conn.commit();
        conn.setAutoCommit(true);
        conn.close();
        connectionHolder.remove();
        transactionActive.set(false);
    }
    public static void rollback() throws SQLException {
        if (!transactionActive.get()) {
            return;
        }
        Connection conn = connectionHolder.get();
        conn.rollback();
        conn.setAutoCommit(true);
        conn.close();
        connectionHolder.remove();
        transactionActive.set(false);
    }
    public static Connection getConnection() {
        return connectionHolder.get();
    }
}
// 2. 事務(wù)注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SimpleTransactional {
    Class<? extends Throwable>[] rollbackFor() default {RuntimeException.class};
}
// 3. 動(dòng)態(tài)代理處理器
public class TransactionProxy implements InvocationHandler {
    private Object target;
    public TransactionProxy(Object target) {
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Method targetMethod = target.getClass().getMethod(method.getName(), 
            method.getParameterTypes());
        // 檢查是否有@SimpleTransactional注解
        if (targetMethod.isAnnotationPresent(SimpleTransactional.class)) {
            SimpleTransactional annotation = targetMethod.getAnnotation(SimpleTransactional.class);
            try {
                // 開啟事務(wù)
                SimpleTransactionManager.begin();
                // 執(zhí)行業(yè)務(wù)方法
                Object result = method.invoke(target, args);
                // 提交事務(wù)
                SimpleTransactionManager.commit();
                return result;
            } catch (Throwable e) {
                // 判斷是否需要回滾
                for (Class<? extends Throwable> rollbackEx : annotation.rollbackFor()) {
                    if (rollbackEx.isAssignableFrom(e.getClass())) {
                        SimpleTransactionManager.rollback();
                        break;
                    }
                }
                throw e;
            }
        } else {
            return method.invoke(target, args);
        }
    }
}

總結(jié):事務(wù)的完整生命周期 ??

  1. 代理創(chuàng)建:Spring容器啟動(dòng)時(shí),為@Transactional標(biāo)注的Bean創(chuàng)建代理
  2. 方法調(diào)用:通過代理調(diào)用方法,進(jìn)入TransactionInterceptor.invoke()
  3. 獲取屬性:解析@Transactional注解的配置
  4. 決策事務(wù):根據(jù)傳播行為,決定新建、加入還是掛起事務(wù)
  5. 開啟事務(wù):獲取數(shù)據(jù)庫連接,設(shè)置autoCommit=false
  6. 執(zhí)行業(yè)務(wù):調(diào)用原始業(yè)務(wù)方法
  7. 異常處理:根據(jù)異常類型決定回滾或提交
  8. 提交/回滾:提交事務(wù)或回滾事務(wù)
  9. 清理資源:關(guān)閉連接,清理ThreadLocal

最后的思考 ??

通過源碼分析,我們發(fā)現(xiàn)SpringBoot事務(wù)的本質(zhì)是:

  1. 基于AOP的攔截
  2. 基于ThreadLocal的資源管理
  3. 基于JDBC Connection的autoCommit控制

理解了這些,你就能:

  • 解釋為什么自調(diào)用失效
  • 理解傳播行為的底層實(shí)現(xiàn)
  • 知道事務(wù)同步管理器的工作原理
  • 調(diào)試復(fù)雜的事務(wù)問題
  • 甚至自己實(shí)現(xiàn)一個(gè)簡單的事務(wù)框架

下次遇到事務(wù)問題,不要只是重啟應(yīng)用,打開調(diào)試日志,跟蹤源碼,你會(huì)發(fā)現(xiàn)每個(gè)異常背后,都有一個(gè)清晰的邏輯鏈。這就是從“會(huì)用框架”到“懂框架”的蛻變!??

源碼如詩,每一行都藏著智慧。讀懂了它,你就讀懂了SpringBoot的靈魂。 ? ??

(現(xiàn)在,你可以自信地在團(tuán)隊(duì)分享:“我知道@Transactional的每一行代碼在做什么!” 這種感覺,比加薪還棒!????)

到此這篇關(guān)于SpringBoot事務(wù)源碼從注解到數(shù)據(jù)庫的“奇幻漂流”的文章就介紹到這了,更多相關(guān)SpringBoot事務(wù)源碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

任丘市| 定结县| 濉溪县| 岫岩| 石棉县| 高州市| 容城县| 剑川县| 大邑县| 房产| 广河县| 营口市| 淮阳县| 武山县| 天长市| 芒康县| 娄烦县| 剑阁县| 上林县| 南郑县| 呼图壁县| 积石山| 金川县| 师宗县| 沙雅县| 麻栗坡县| 通海县| 临沭县| 长垣县| 南澳县| 玉山县| 兴海县| 专栏| 汤阴县| 安新县| 五华县| 安图县| 皋兰县| 龙口市| 台北市| 兴隆县|