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

在Spring?Boot中MyBatis?的自動提交行為全解析(最新整理)

 更新時間:2026年01月23日 10:19:30   作者:chxii  
在Spring?Boot中,MyBatis的“自動提交”行為由Spring框架控制,而不是MyBatis本身,在無事務注解的情況下,Spring會為每個數(shù)據(jù)庫操作開啟并立即提交一個獨立事務,接下來通過本文給大家介紹在Spring?Boot中MyBatis的自動提交行為解析,感興趣的朋友跟隨小編一起看看吧

在 Spring Boot 中,MyBatis 的“自動提交”行為并不是 MyBatis 自己實現(xiàn)的,而是 由 Spring 框架通過事務管理器(PlatformTransactionManager)統(tǒng)一控制的。MyBatis 原生默認是 不自動提交(autoCommit=false),但在 Spring Boot 集成環(huán)境下,是否提交由 Spring 的事務傳播機制決定:

一、核心結論

場景是否自動提交?控制者
原生 MyBatis(無 Spring)? 默認不提交,需手動 sqlSession.commit()MyBatis 自身
Spring Boot + MyBatis(無 @Transactional自動提交(每條 SQL 獨立事務)Spring 的 DataSourceTransactionManager
Spring Boot + MyBatis(有 @Transactional? 方法結束前不提交,成功則提交,異常則回滾Spring 事務管理

? 所以你看到的“自動提交”,其實是 Spring 在方法無事務注解時,為每個數(shù)據(jù)庫操作開啟并立即提交一個獨立事務。

二、Spring Boot 如何集成 MyBatis?

Spring Boot 通過 mybatis-spring-boot-starter 自動配置:

  • 創(chuàng)建 SqlSessionFactory
  • 創(chuàng)建 SqlSessionTemplate(線程安全的 SqlSession 代理)
  • 注冊 Mapper 接口為 Spring Bean

關鍵點:不再直接使用原生 SqlSession,而是通過 SqlSessionTemplate 代理調用。

三、源碼分析:為什么“自動提交”?

1.SqlSessionTemplate的代理機制

SqlSessionTemplate 是 MyBatis-Spring 提供的線程安全 SqlSession 實現(xiàn),它內部持有一個 SqlSessionInterceptor(動態(tài)代理)。

當調用 Mapper 方法(如 userMapper.insert(user))時,實際執(zhí)行路徑:

Mapper Proxy → SqlSessionTemplate → SqlSessionInterceptor.invoke()

查看 SqlSessionInterceptor.invoke() 源碼(簡化版):

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    // 1. 獲取當前 Spring 管理的 SqlSession(可能已存在事務上下文)
    SqlSession sqlSession = getSqlSession(
        SqlSessionTemplate.this.sqlSessionFactory,
        SqlSessionTemplate.this.executorType,
        SqlSessionTemplate.this.exceptionTranslator
    );
    try {
        // 2. 執(zhí)行 SQL(如 insert/update/delete/select)
        Object result = method.invoke(sqlSession, args);
        // 3. 如果當前沒有 Spring 事務,則立即 commit(僅對更新操作)
        if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
            sqlSession.commit(true); // true 表示強制提交
        }
        return result;
    } catch (Throwable t) {
        // 異常處理...
        throw t;
    } finally {
        // 4. 如果不是 Spring 事務管理的 SqlSession,則關閉它
        if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
            sqlSession.close();
        }
    }
}

?? 關鍵判斷:isSqlSessionTransactional(...)

  • 如果當前線程 已有 Spring 事務(即處于 @Transactional 方法中),則返回 true,不提交、不關閉,交由 Spring 統(tǒng)一管理。
  • 如果 沒有 Spring 事務,則返回 false立即提交并關閉 SqlSession。

這就解釋了“自動提交”的來源!

2.isSqlSessionTransactional的實現(xiàn)邏輯

該方法檢查當前 SqlSession 是否被 Spring 事務管理:

// org.mybatis.spring.SqlSessionUtils
public static boolean isSqlSessionTransactional(SqlSession session, SqlSessionFactory sessionFactory) {
    // 從 ThreadLocal 中獲取 Spring 管理的 SqlSession
    SqlSessionHolder holder = (SqlSessionHolder) TransactionSynchronizationManager
        .getResource(sessionFactory);
    return (holder != null) && (holder.getSqlSession() == session);
}
  • TransactionSynchronizationManager.getResource() 是 Spring 事務同步的核心機制。
  • 只有在 @Transactional 方法中,Spring 才會提前將 SqlSession 綁定到 ThreadLocal。
  • 否則,holder == null,返回 false → 觸發(fā)自動提交。

3. Spring 事務如何接管 SqlSession?

當方法標注 @Transactional 時,Spring 會:

  1. 在方法開始前,通過 DataSourceTransactionManager 開啟 JDBC 事務(connection.setAutoCommit(false))。
  2. 調用 SqlSessionUtils.getSqlSession() 時,發(fā)現(xiàn)已有事務,復用同一個 Connection,并將其包裝為 SqlSession 存入 ThreadLocal。
  3. 方法結束時,根據(jù)是否拋異常,調用 commit() 或 rollback()。
  4. 最終由 Spring 負責 close()。

此時,SqlSessionTemplate 不會干預提交行為。

四、驗證實驗

場景 1:無@Transactional

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    public void saveUser(User user) {
        userMapper.insert(user); // 自動提交!
    }
}

? 插入成功,即使后續(xù)代碼拋異常,數(shù)據(jù)也不會回滾。

場景 2:有@Transactional

@Transactional
public void saveUserWithTx(User user) {
    userMapper.insert(user);
    throw new RuntimeException("模擬異常"); // 數(shù)據(jù)會回滾!
}

? 插入被回滾,因為整個方法是一個事務。

五、配置項說明

雖然 MyBatis 有 autoCommit 配置,但在 Spring Boot 中 幾乎無效,因為:

  • Spring 通過 DataSource 獲取 Connection,并由事務管理器控制 setAutoCommit()。
  • MyBatis 的 autoCommit 參數(shù)在 SqlSessionFactoryBean 中會被忽略(或覆蓋)。

所以,不要依賴 MyBatis 的 autoCommit,而應使用 Spring 的 @Transactional

六、總結

問題答案
Spring Boot 中 MyBatis 為何“自動提交”?因為 Spring 在無事務方法中,為每次 Mapper 調用創(chuàng)建獨立事務并立即提交。
源碼關鍵類SqlSessionTemplate.SqlSessionInterceptor + SqlSessionUtils
控制提交行為的方式使用 @Transactional 注解,而非 MyBatis 配置
是否應關閉“自動提交”?不需要關閉,這是 Spring 的合理默認行為;需事務時加 @Transactional 即可

?? 最佳實踐

  • 簡單查詢/單條寫入:無需 @Transactional,享受自動提交。
  • 多操作一致性要求:必須加 @Transactional。
  • 永遠不要在 Service 層手動調用 sqlSession.commit()

通過 Spring 的聲明式事務,開發(fā)者既能獲得“自動提交”的便利,又能靈活控制復雜事務,這正是 Spring Boot + MyBatis 的強大之處。

到此這篇關于在Spring Boot中MyBatis 的自動提交行為全解析(最新整理)的文章就介紹到這了,更多相關Spring Boot MyBatis 自動提交內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • SpringBoot中加載與Bean處理的細節(jié)剖析教程

    SpringBoot中加載與Bean處理的細節(jié)剖析教程

    這篇文章主要為大家詳細介紹了SpringBoot中加載與Bean處理的細節(jié)剖析,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2025-08-08
  • Lombok 的@StandardException注解解析

    Lombok 的@StandardException注解解析

    @StandardException 是一個實驗性的注解,添加到 Project Lombok 的 v__1.18.22 版本中,在本教程中,我們將使用 Lombok 的 @StandardException 注解自動生成異常類型類的構造函數(shù),需要的朋友可以參考下
    2023-05-05
  • Spring Boot應用程序同時支持HTTP和HTTPS協(xié)議的實現(xiàn)方法

    Spring Boot應用程序同時支持HTTP和HTTPS協(xié)議的實現(xiàn)方法

    如今,企業(yè)級應用程序的常見場景是同時支持HTTP和HTTPS兩種協(xié)議,這篇文章考慮如何讓Spring Boot應用程序同時支持HTTP和HTTPS兩種協(xié)議,需要的朋友可以參考下
    2019-10-10
  • Spring?Cloud?OpenFeign?遠程調用

    Spring?Cloud?OpenFeign?遠程調用

    這篇文章主要介紹了Spring?Cloud?OpenFeign?遠程調用,本文通過遠程調用的GitHub開放API用到的OpenFeign作為示例代碼作為入口進行講解。然后以圖解+解讀源碼的方式深入剖析了OpenFeign的運行機制和架構設計,需要的朋友可以參考一下
    2022-08-08
  • java實現(xiàn)二分法查找出數(shù)組重復數(shù)字

    java實現(xiàn)二分法查找出數(shù)組重復數(shù)字

    這篇文章主要為大家詳細介紹了java實現(xiàn)二分法查找出數(shù)組重復數(shù)字,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • 簡單了解java自定義和自然排序

    簡單了解java自定義和自然排序

    這篇文章主要介紹了簡單了解java自定義和自然排序,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-07-07
  • Springboot創(chuàng)建子父工程過程圖解

    Springboot創(chuàng)建子父工程過程圖解

    這篇文章主要介紹了Springboot創(chuàng)建子父工程過程圖解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-02-02
  • SpringBoot+JPA?分頁查詢指定列并返回指定實體方式

    SpringBoot+JPA?分頁查詢指定列并返回指定實體方式

    這篇文章主要介紹了SpringBoot+JPA?分頁查詢指定列并返回指定實體方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • java實現(xiàn)發(fā)送email小案例

    java實現(xiàn)發(fā)送email小案例

    這篇文章主要為大家詳細介紹了java實現(xiàn)發(fā)送email小案例,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • Java中泛型學習之細節(jié)篇

    Java中泛型學習之細節(jié)篇

    泛型在java中有很重要的地位,在面向對象編程及各種設計模式中有非常廣泛的應用,下面這篇文章主要給大家介紹了關于Java中泛型細節(jié)的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-02-02

最新評論

南澳县| 霍城县| 清徐县| 平罗县| 新余市| 托克逊县| 兰考县| 环江| 峡江县| 海晏县| 原平市| 云南省| 静海县| 沾化县| 观塘区| 常州市| 罗定市| 香格里拉县| 会泽县| 前郭尔| 洮南市| 平阳县| 凤山县| 宁明县| 南雄市| 乌拉特后旗| 镇巴县| 景泰县| 岚皋县| 房产| 自贡市| 旺苍县| 拜泉县| 乌拉特前旗| 和政县| 岳池县| 陈巴尔虎旗| 金华市| 怀仁县| 习水县| 老河口市|