记录一次spring的事务管理器mybatis一级缓存的坑

探讨了在使用MyBatis框架时,由于事务管理不当导致的一级缓存问题。在事务中连续查询同一SQL语句,参数相同,但查询结果不一致。问题在于事务内的两次查询使用了同一个sqlSessionProxy对象,导致一级缓存生效。解决方法是在MyBatis配置文件中禁用一级缓存。

  原因: 一个@Transactional注解的方法中,连续查询了两次sql,参数一致,两次查询过后再update

未加事务时,一切正常。加上事务后,导致两次查询结果不一致,debug后发现加入注解后,两次的sqlSessionProxy对象一致,导致一级缓存生效。

下面是未加事务时,sqlSessionProxy对象

 

 

下面是加上注解后,sqlSessionProxy对象

解决方案: 由于项目中引入了集中缓存redis,并自己对@Cacheable注解进行了自定义时间属性的扩展,故禁用mybatis的一级缓存。在mybatis的配置文件中加入

<setting name="localCacheScope" value="STATEMENT" />
<think>好的,我现在需要回答用户关于Spring集成MyBatis一级缓存的默认开启状态的问题。首先,我需要回忆一下MyBatisSpring整合时的一级缓存机制。 根据用户提供的引用内容,特别是引用[3]提到,当MyBatisSpring集成时,默认每次执行SQL语句都会创建一个新的SqlSession,这会导致一级缓存无法生效,因为一级缓存是会话级别的,需要在同一个SqlSession中才能起作用。而引用[2]则指出,如果开启了事务,Spring会使用同一个数据库连接,从而一级缓存生效。这说明一级缓存是否生效与事务的使用有关。 接下来,我需要确定默认情况下是否开启事务。Spring的声明式事务管理通常需要手动配置,比如使用@Transactional注解或者在配置文件中定义事务管理器。如果没有显式配置事务,那么默认情况下可能不会开启事务,因此每次执行SQL都会创建新的SqlSession,导致一级缓存不生效。 另外,引用[1]提到,整合后使用的是SqlSessionTemplate,它替代了默认的DefaultSqlSession。SqlSessionTemplate在每次执行SQL时会检查是否存在活跃的事务,如果有,则复用SqlSession;否则可能会关闭或新建。这也支持了事务存在与否对一级缓存的影响。 综合这些信息,可以得出结论:在Spring集成MyBatis时,一级缓存在没有事务的情况下默认不生效,因为SqlSession被频繁创建和销毁。而当启用事务时,同一事务内会复用SqlSession,使一级缓存生效。因此,一级缓存的功能是否开启取决于事务的使用,而不是MyBatis本身的配置。</think>### Spring集成MyBatis一级缓存的开启状态分析 在SpringMyBatis整合的场景中,**一级缓存默认存在但实际生效需满足特定条件**,具体逻辑如下: 1. **一级缓存的默认存在性** MyBatis原生设计中,一级缓存(SqlSession级别缓存)默认始终存在且无法关闭[^3]。但Spring整合MyBatis时,**缓存是否生效取决于SqlSession的复用情况**。 2. **Spring整合对SqlSession的影响** - 通过`SqlSessionTemplate`管理会话,默认行为是:**每次执行SQL后关闭SqlSession**(除非处于事务中)[^1][^3] - 非事务场景下:每次SQL执行都会创建新SqlSession → **一级缓存无法跨方法生效** - 事务场景下:同一事务内复用SqlSession → **一级缓存生效**[^2] 3. **事务对一级缓存的控制逻辑** 启用事务时(例如使用`@Transactional`注解): ```java @Transactional public void queryData() { // 第一次查询(查数据库) userMapper.selectById(1); // 第二次查询(命中一级缓存) userMapper.selectById(1); } ``` 此时Spring会绑定同一个数据库连接和SqlSession,使一级缓存生效[^2]。 ### 总结结论 | 场景 | 一级缓存生效状态 | |---------------------|------------------| | 未启用事务时 | 默认不生效 | | 启用事务时 | 默认生效 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值