SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@xxx] was not registered for synchro

本文探讨了SpringBoot项目中Mybatis日志报错信息,解析了SqlSession未被Spring管理的原因,并给出了将事务交给Spring管理的方法,包括如何在方法上添加@Transactional。通过实例展示了事务管理前后日志的变化。

1、报错场景

在搞SpringBoot项目的时候,把Mybatis打印日志的配置打开后,发现每条Sql打印的时候都会在前面打印如下的信息,强迫症受不了,得查查为什么;

Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@521978e4] was not registered for synchronization because synchronization is not active
JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@5bb2b956] will not be managed by Spring
==>  Preparing: select * from xxx where xxx = ? and xxx = ?
==> Parameters: opHQA5gq2qfn1DRl069YOLv1Wv0Q(String), 0(Integer)
<==    Columns: xxx, xxx, xxx, xxx
<==        Row: xxx, xxx, xxx, xxx
<==      Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@521978e4]

前面打印的内容意思大概是:这次的SqlSession未注册进来,同步关着呢哎,所以你这玩意Spring不会管理的;

2、问题原因及解决办法

原因就是你现在这个事务吧,不是Spring管理着呢,是你的数据库插件Mybatis或者MybatisPlus给你管理呢,所以Spring给你温馨提醒了一下而已,又没有报错!但是,有一种情况,比如你的方法里面逻辑比较多,增删改查的SQL比较多的话,而你自己又不清楚事务怎么管理的话,推荐你把@Transactional给加到方法上面,让Spring接管起来当前的事务,将来报错更好回滚。

当你把@Transactional加到方法上面时;

@Override
@Transactional
public Boolean xxxx(String xxx, String xxx) {
    Txxx txxx = txxxMapper.xxx(xxx, Integer.parseInt(xxx));
    //...
    return true;
}

再次打印日志的话就变成了这样:

Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3ba27661]
JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@57d27e73] will be managed by Spring
==>  Preparing: select * from xxx where xxx = ? and xxx = ?
==> Parameters: opHQA5gq2qfn1DRl069YOLv1Wv1Q(String), 0(Integer)
<==    Columns: xxx, xxx, xxx, xxx
<==        Row: xxx, xxx, xxx, xxx
<==      Total: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3ba27661]
Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3ba27661]
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3ba27661]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3ba27661]

能看见Spring已经will be managed by Spring帮你管理了;

### MyBatis SqlSession未注册同步的原因分析 当遇到`SqlSession [...] was not registered for synchronization because synchronization is not active`错误时,这通常表明当前事务管理器未能成功激活事务同步机制。在SSM(Spring、Spring MVC 和 MyBatis)集成开发环境中,这种问题可能源于以下几个方面: #### 1. **事务配置不正确** 如果Spring中的事务管理器没有被正确定义或者未启用声明式事务支持,则可能导致MyBatis的`SqlSession`无法参与事务同步[^1]。 解决方案之一是在Spring配置文件中确保已启用了事务管理功能。例如,在XML配置中应包含如下内容: ```xml <tx:annotation-driven transaction-manager="transactionManager"/> ``` 同时需确认定义了一个合适的事务管理器实例,比如基于JDBC的数据源事务管理器: ```xml <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> ``` 对于注解驱动的方式,还需保证相应的Service类上标注有`@Transactional`注解来开启方法级别的事务控制。 #### 2. **线程上下文中缺少事务绑定** 即使事务管理已经设置好,但如果执行SQL操作所在的线程并未关联任何活动事务,那么同样会出现上述警告信息并阻止正常提交更改至数据库[^1]。 要解决此情况可以检查是否存在异步调用或其他多线程场景干扰了主线程上的事务传播行为;另外也可以尝试通过手动方式强制让某个特定的操作运行在一个新创建出来的独立事务当中去完成其工作流程。 以下是调整后的代码片段展示如何显式指定新的事务属性: ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override @Transactional(propagation = Propagation.REQUIRES_NEW) public void addUser(User user){ userMapper.insertUser(user); } } ``` 这里设置了propagation参数为REQUIRES_NEW意味着每次调用addUser()函数都会启动一个新的事务而不管外部是否有现存事务存在。 #### 3. **DataSource连接池配置异常** 某些情况下,由于数据源本身存在问题也可能间接引发此类现象。因此有必要重新审视项目里关于数据库链接资源的相关设定是否合理有效。特别是像C3P0,HikariCP这类第三方库所提供的高级特性选项可能会对最终效果产生影响。 例如HikariCP的一些重要参数如maximumPoolSize, connectionTimeout等都需要依据实际需求精心调节才能达到最佳性能表现同时也减少潜在风险隐患。 最后附带一段简单的测试程序用于验证整个链路能否顺畅运作无误: ```java @SpringBootTest class ApplicationTests { @Resource(name = "sqlSessionFactory") private SqlSessionFactory sqlSessionFactory; @Test void contextLoads(){ try(SqlSession session=sqlSessionFactory.openSession(false)){ System.out.println(session.getConnection().isClosed()); }catch(Exception e){ fail(e.getMessage()); } } } ``` 以上即是对该问题较为全面深入剖析以及相应对策建议的内容总结。 相关问题
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cgv3

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值