Spring与MyBatis事务集成核心是:SqlSessionFactoryBean必须显式指定同一DataSource,事务管理器必须为DataSourceTransactionManager且共用该DataSource,@MapperScan精准扫描接口包,自调用事务因AOP代理限制不生效。

Spring 与 MyBatis 的事务集成,核心在于让 MyBatis 的 SQL 执行真正纳入 Spring 的声明式事务控制体系。不是加个 @Transactional 就自动生效,关键配置缺一不可。
SqlSessionFactoryBean 必须显式绑定 DataSource
当项目中存在多个数据源(如主从、读写分离),SqlSessionFactoryBean 若未显式调用 setDataSource(),Spring 会尝试自动注入——但因找不到唯一 DataSource Bean 而抛出 NoUniqueBeanDefinitionException。
- 在
@Configuration类中,直接传入已定义好的DataSource实例,避免字段@Autowired注入 - XML 配置下,确保
<property name="dataSource" ref="xxxDataSource"/>中的ref值与<bean id="xxxDataSource">完全一致 - 这是事务能“触达” SQL 执行层的前提:只有同一个
DataSource,才能共享物理数据库连接和事务上下文
事务管理器必须是 DataSourceTransactionManager
MyBatis 底层基于 JDBC 操作,事务边界由 DataSource 控制。若误配为 JtaTransactionManager,@Transactional 将完全静默失效——不报错、不回滚、数据悄悄出错。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 确认事务管理器类型为
org.springframework.jdbc.datasource.DataSourceTransactionManager - 构造时必须传入与
SqlSessionFactoryBean相同的DataSource实例,否则事务无法跨到 SQL 执行环节 - XML 中检查
class属性是否手滑写成JtaTransactionManager,尤其在复制粘贴旧配置时易出错
@MapperScan 要精准指向接口包路径
@MapperScan("com.example.mapper") 扫描的是 Mapper 接口,不是 XML 文件目录,也不是实现类或抽象类路径。扫错则 Spring 找不到任何 Mapper Bean,后续所有调用都会报 Invalid bound statement。
立即学习“Java免费学习笔记(深入)”;
- 接口需使用
@Mapper注解,或统一由@MapperScan扫描其所在包 - 确保接口方法名与 XML 中
<select id="methodName">或@Select注解中的标识严格匹配 - 扫描路径末尾不加斜杠,如
"com.example.mapper"正确,"com.example.mapper/"可能导致漏扫
注意自调用导致的事务失效
Service 内部方法 A 调用本类另一个带 @Transactional 的方法 B,事务不会生效。这是 Spring AOP 代理机制限制:this.xxx() 绕过了代理对象,事务切面根本没机会介入。
- 解决方式:将方法 B 提取到另一个 Service Bean 中,通过依赖注入调用
- 或使用
AopContext.currentProxy()强制走代理(需开启expose-proxy="true"),但属侵入式写法,不推荐 - 更稳妥的做法是重构业务逻辑,避免同一 Bean 内的事务方法互相调用

















