在Spring Boot中MyBatis 的自动提交行为全解析(最新整理)

 更新时间:2026年01月23日 10:19:30   作者:chxii  
在Spring Boot中,MyBatis的“自动提交”行为由Spring框架控制,而不是MyBatis本身,在无事务注解的情况下,Spring会为每个数据库操作开启并立即提交一个独立事务,接下来通过本文给大家介绍在Spring Boot中MyBatis的自动提交行为解析,感兴趣的朋友跟随小编一起看看吧

在 Spring Boot 中,MyBatis 的“自动提交”行为并不是 MyBatis 自己实现的,而是 由 Spring 框架通过事务管理器(PlatformTransactionManager)统一控制的。MyBatis 原生默认是 不自动提交(autoCommit=false),但在 Spring Boot 集成环境下,是否提交由 Spring 的事务传播机制决定:

一、核心结论

场景是否自动提交?控制者
原生 MyBatis(无 Spring)❌ 默认不提交,需手动 sqlSession.commit()MyBatis 自身
Spring Boot + MyBatis(无 @Transactional✅ 自动提交(每条 SQL 独立事务)Spring 的 DataSourceTransactionManager
Spring Boot + MyBatis(有 @Transactional❌ 方法结束前不提交,成功则提交,异常则回滚Spring 事务管理

✅ 所以你看到的“自动提交”,其实是 Spring 在方法无事务注解时,为每个数据库操作开启并立即提交一个独立事务

二、Spring Boot 如何集成 MyBatis?

Spring Boot 通过 mybatis-spring-boot-starter 自动配置:

  • 创建 SqlSessionFactory
  • 创建 SqlSessionTemplate(线程安全的 SqlSession 代理)
  • 注册 Mapper 接口为 Spring Bean

关键点:不再直接使用原生 SqlSession,而是通过 SqlSessionTemplate 代理调用。

三、源码分析:为什么“自动提交”?

1.SqlSessionTemplate的代理机制

SqlSessionTemplate 是 MyBatis-Spring 提供的线程安全 SqlSession 实现,它内部持有一个 SqlSessionInterceptor(动态代理)。

当调用 Mapper 方法(如 userMapper.insert(user))时,实际执行路径:

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. 执行 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 统一管理。
  • 如果 没有 Spring 事务,则返回 false立即提交并关闭 SqlSession

这就解释了“自动提交”的来源!

2.isSqlSessionTransactional的实现逻辑

该方法检查当前 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 → 触发自动提交。

3. Spring 事务如何接管 SqlSession?

当方法标注 @Transactional 时,Spring 会:

  1. 在方法开始前,通过 DataSourceTransactionManager 开启 JDBC 事务(connection.setAutoCommit(false))。
  2. 调用 SqlSessionUtils.getSqlSession() 时,发现已有事务,复用同一个 Connection,并将其包装为 SqlSession 存入 ThreadLocal
  3. 方法结束时,根据是否抛异常,调用 commit() 或 rollback()
  4. 最终由 Spring 负责 close()

此时,SqlSessionTemplate 不会干预提交行为。

四、验证实验

场景 1:无@Transactional

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

✅ 插入成功,即使后续代码抛异常,数据也不会回滚。

场景 2:有@Transactional

@Transactional
public void saveUserWithTx(User user) {
    userMapper.insert(user);
    throw new RuntimeException("模拟异常"); // 数据会回滚!
}

❌ 插入被回滚,因为整个方法是一个事务。

五、配置项说明

虽然 MyBatis 有 autoCommit 配置,但在 Spring Boot 中 几乎无效,因为:

  • Spring 通过 DataSource 获取 Connection,并由事务管理器控制 setAutoCommit()
  • MyBatis 的 autoCommit 参数在 SqlSessionFactoryBean 中会被忽略(或覆盖)。

所以,不要依赖 MyBatis 的 autoCommit,而应使用 Spring 的 @Transactional

六、总结

问题答案
Spring Boot 中 MyBatis 为何“自动提交”?因为 Spring 在无事务方法中,为每次 Mapper 调用创建独立事务并立即提交。
源码关键类SqlSessionTemplate.SqlSessionInterceptor + SqlSessionUtils
控制提交行为的方式使用 @Transactional 注解,而非 MyBatis 配置
是否应关闭“自动提交”?不需要关闭,这是 Spring 的合理默认行为;需事务时加 @Transactional 即可

💡 最佳实践

  • 简单查询/单条写入:无需 @Transactional,享受自动提交。
  • 多操作一致性要求:必须加 @Transactional
  • 永远不要在 Service 层手动调用 sqlSession.commit()

通过 Spring 的声明式事务,开发者既能获得“自动提交”的便利,又能灵活控制复杂事务,这正是 Spring Boot + MyBatis 的强大之处。

到此这篇关于在Spring Boot中MyBatis 的自动提交行为全解析(最新整理)的文章就介绍到这了,更多相关Spring Boot MyBatis 自动提交内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 深入分析Comparable与Comparator及Clonable三个Java接口

    深入分析Comparable与Comparator及Clonable三个Java接口

    接口不是类,而是对类的一组需求描述,这些类要遵从接口描述的统一格式进行定义,这篇文章主要为大家详细介绍了Java的Comparable,Comparator和Cloneable的接口,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-05-05
  • Spring中的自动装配机制详解

    Spring中的自动装配机制详解

    这篇文章主要介绍了Spring中的自动装配机制详解,自动装配就是会通过Spring的上下文为你找出相应依赖项的类,通俗的说就是Spring会在上下文中自动查找,并自动给Bean装配与其相关的属性,需要的朋友可以参考下
    2023-08-08
  • Java 实现贪吃蛇游戏的示例

    Java 实现贪吃蛇游戏的示例

    这篇文章主要介绍了Java 如何实现贪吃蛇游戏,帮助大家更好的理解和学习使用Java,感兴趣的朋友可以了解下
    2021-03-03
  • Java实现复杂的进制转换器功能示例

    Java实现复杂的进制转换器功能示例

    这篇文章主要介绍了Java实现复杂的进制转换器功能,结合实例形式分析了java数学运算的相关实现技巧,需要的朋友可以参考下
    2017-01-01
  • Java单例模式实例简述

    Java单例模式实例简述

    这篇文章主要介绍了Java单例模式,在Java应用程序设计中有着非常重要的作用,本文以实例形式对此加以简单分析,需要的朋友可以参考下
    2014-09-09
  • 浅谈java监听器的作用

    浅谈java监听器的作用

    这篇文章主要介绍了浅谈java监听器的作用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • windows启动jar的三种方式小结

    windows启动jar的三种方式小结

    JAR(Java Archive)文件是Java程序的封装格式,使得多个.class文件及其相关资源可以被打包成一个文件,方便发布和分发,这篇文章主要介绍了windows启动jar的三种方式,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-09-09
  • 如何开启控制台输出mybatis执行的sql日志问题

    如何开启控制台输出mybatis执行的sql日志问题

    这篇文章主要介绍了如何开启控制台输出mybatis执行的sql日志问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • Java实现超大Excel文件解析(XSSF,SXSSF,easyExcel)

    Java实现超大Excel文件解析(XSSF,SXSSF,easyExcel)

    这篇文章主要为大家详细介绍了如何利用Java语言实现超大Excel文件解析(XSSF,SXSSF,easyExcel)以及速度的对比,感兴趣的可以了解一下
    2022-07-07
  • Spring Boot Admin 快速入门详解

    Spring Boot Admin 快速入门详解

    这篇文章主要介绍了SpringBoot Admin 使用指南(推荐),Spring Boot Admin 是一个管理和监控你的 Spring Boot 应用程序的应用程序,非常具有实用价值,需要的朋友可以参考下
    2021-11-11

最新评论