You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot使用@Transactional抛出异常后事务未回滚问题咨询

问题根因

你遇到的问题核心是自定义多数据源场景下,MyBatis未和Spring事务上下文绑定:MyBatis执行DAO操作时拿的是独立的自动提交连接,执行SQL后直接提交到数据库,Spring事务管理器回滚的是另一个事务上下文内的连接,所以回滚不生效。

修复配置
  • 第一步:注册对应数据源的事务管理器
    自定义数据源必须显式注册对应的事务管理器,代码示例:
@Bean(name = "aTransactionManager")
public DataSourceTransactionManager transactionManager(@Qualifier(MYBATIS_DATASOURCE_A) DataSource dataSource) {
    return new DataSourceTransactionManager(dataSource);
}

然后修改Service层的@Transactional注解,指定使用对应事务管理器:

@Transactional(rollbackFor = Exception.class, transactionManager = "aTransactionManager")
  • 第二步:配置MyBatis SqlSessionTemplate并绑定到Mapper扫描
    Spring管理事务场景下必须用SqlSessionTemplate来绑定事务上下文的连接,不要手动创建SqlSession。新增配置:
@Bean(name = "aSqlSessionTemplate")
public SqlSessionTemplate sqlSessionTemplate(@Qualifier(A_SESSION_FACTORY) SqlSessionFactory sqlSessionFactory) {
    return new SqlSessionTemplate(sqlSessionFactory);
}

如果用了@MapperScan扫描Mapper接口,需要指定对应的SqlSessionTemplate引用:

@MapperScan(basePackages = "你的A数据源Mapper所在包路径", sqlSessionTemplateRef = "aSqlSessionTemplate")
  • 第三步:显式关闭数据源默认自动提交
    修改你的DataSource配置,新增默认自动提交关闭配置:
PooledDataSource dataSource = new PooledDataSource();
// 原有配置不变
dataSource.setDefaultAutoCommit(false);
可开启的定位日志

如果需要进一步验证连接绑定逻辑,可开启以下日志:

  • MyBatis运行日志:配置logging.level.org.mybatis=DEBUG,可以查看MyBatis每次获取的连接ID,和Spring事务日志中的连接ID对比,确认是否复用事务上下文连接
  • 数据源连接日志:配置logging.level.org.apache.ibatis.datasource=DEBUG,可以查看连接的借出、归还状态以及自动提交属性配置
  • JDBC操作日志:配置logging.level.org.springframework.jdbc.core=DEBUG,可以查看每条SQL执行的关联连接、参数、执行结果

内容的提问来源于stack exchange,提问作者Alexandre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 17:24:03