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

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

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

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

一、核心結(jié)論

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

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

二、Spring Boot 如何集成 MyBatis?

Spring Boot 通過(guò) mybatis-spring-boot-starter 自動(dòng)配置:

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

關(guān)鍵點(diǎn):不再直接使用原生 SqlSession,而是通過(guò) SqlSessionTemplate 代理調(diào)用。

三、源碼分析:為什么“自動(dòng)提交”?

1.SqlSessionTemplate的代理機(jī)制

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

當(dāng)調(diào)用 Mapper 方法(如 userMapper.insert(user))時(shí),實(shí)際執(zhí)行路徑:

Mapper Proxy → SqlSessionTemplate → SqlSessionInterceptor.invoke()

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

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    // 1. 獲取當(dāng)前 Spring 管理的 SqlSession(可能已存在事務(wù)上下文)
    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. 如果當(dāng)前沒(méi)有 Spring 事務(wù),則立即 commit(僅對(duì)更新操作)
        if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
            sqlSession.commit(true); // true 表示強(qiáng)制提交
        }
        return result;
    } catch (Throwable t) {
        // 異常處理...
        throw t;
    } finally {
        // 4. 如果不是 Spring 事務(wù)管理的 SqlSession,則關(guān)閉它
        if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
            sqlSession.close();
        }
    }
}

?? 關(guān)鍵判斷:isSqlSessionTransactional(...)

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

這就解釋了“自動(dòng)提交”的來(lái)源!

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

該方法檢查當(dāng)前 SqlSession 是否被 Spring 事務(wù)管理:

// 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 事務(wù)同步的核心機(jī)制。
  • 只有在 @Transactional 方法中,Spring 才會(huì)提前將 SqlSession 綁定到 ThreadLocal。
  • 否則,holder == null,返回 false → 觸發(fā)自動(dòng)提交。

3. Spring 事務(wù)如何接管 SqlSession?

當(dāng)方法標(biāo)注 @Transactional 時(shí),Spring 會(huì):

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

此時(shí),SqlSessionTemplate 不會(huì)干預(yù)提交行為。

四、驗(yàn)證實(shí)驗(yàn)

場(chǎng)景 1:無(wú)@Transactional

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

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

場(chǎng)景 2:有@Transactional

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

? 插入被回滾,因?yàn)檎麄€(gè)方法是一個(gè)事務(wù)。

五、配置項(xiàng)說(shuō)明

雖然 MyBatis 有 autoCommit 配置,但在 Spring Boot 中 幾乎無(wú)效,因?yàn)椋?/p>

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

所以,不要依賴 MyBatis 的 autoCommit,而應(yīng)使用 Spring 的 @Transactional

六、總結(jié)

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

?? 最佳實(shí)踐

  • 簡(jiǎn)單查詢/單條寫入:無(wú)需 @Transactional,享受自動(dòng)提交。
  • 多操作一致性要求:必須加 @Transactional。
  • 永遠(yuǎn)不要在 Service 層手動(dòng)調(diào)用 sqlSession.commit()!

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

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

相關(guān)文章

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

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

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

    Lombok 的@StandardException注解解析

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

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

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

    Spring?Cloud?OpenFeign?遠(yuǎn)程調(diào)用

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

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

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

    簡(jiǎn)單了解java自定義和自然排序

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

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

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

    SpringBoot+JPA?分頁(yè)查詢指定列并返回指定實(shí)體方式

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

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

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

    Java中泛型學(xué)習(xí)之細(xì)節(jié)篇

    泛型在java中有很重要的地位,在面向?qū)ο缶幊碳案鞣N設(shè)計(jì)模式中有非常廣泛的應(yīng)用,下面這篇文章主要給大家介紹了關(guān)于Java中泛型細(xì)節(jié)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-02-02

最新評(píng)論

乌拉特前旗| 习水县| 皋兰县| 三台县| 原平市| 嘉黎县| 金华市| 读书| 武义县| 甘肃省| 天津市| 丰镇市| 商丘市| 巢湖市| 黄平县| 庆云县| 东光县| 册亨县| 上犹县| 盖州市| 富阳市| 安阳市| 边坝县| 龙海市| 图木舒克市| 嵩明县| 杭州市| 莆田市| 蕲春县| 江津市| 大厂| 兰坪| 桐乡市| 南丰县| 屏南县| 太和县| 竹溪县| 南溪县| 剑河县| 灌南县| 交城县|