【不懂就问】MyBatis的一级缓存竟然还会引来麻烦? - 掘金
【不懂就问】MyBatis的一级缓存竟然还会引来麻烦? - 掘金 LinkedBear 2020年06月28日 阅读 1252 【不懂就问】MyBatis的一级缓存竟然还会引来麻烦? 【 “不懂就问” ,是一个新的系列,主要整理我的小册群里遇到的一些比较有意思的 / 有难度的 / 容易被讨论起来的问题,并给出问题的解析和方案等等。喜欢的小伙伴们可以点赞关注我鸭 ~ ~ 学习源码可以看看我的小册 ~ ~】 端午假期相信不少小伙伴都在偷偷学习吧(说好了放假一起玩耍呢,结果又背着我学习),这不,刚过了端午,我的一个沙雕程序猿圈子里就有人讨论起来问题了,这个问题聊起来好像挺麻烦,但实际上问题是很简单的,下面咱来讨论下这个问题。 原问题 MyBatis 一级缓存与 SpringFramework 的声明式事务有冲突吗?在 Service 中开启事务,连续查询两次同样的数据,结果两次查询的结果不一致。 —— 使用 Mapper 的 selectById 查出来实体,然后修改实体的属性值,然后再 selectById 一下查出来实体,对比一下之前查出来的,发现查出来的是刚才修改过的实体,不是从数据库查出来的。 —— 如果不开启事务,则两次请求查询的结果是相同的,控制台打印了两次 SQL 。 初步分析 讲道理,看到这个问题,我一下子就猜到是 MyBatis 一级缓存重复读取的问题了。 MyBatis 的一级缓存默认开启,属于 SqlSession 作用范围。在事务开启的期间,同样的数据库查询请求只会查询一次数据库,之后重复查询会从一级缓存中获取。当不开启事务时,同样的多次数据库查询都会发送数据库请求。 上面的都属于基础知识了,不多解释。重点是,他修改的实体是 直接从 MyBatis 的一级缓存中查询出来的 。咱都知道,查询出来的这些实体肯定属于对象,拿到的是对象的引用,咱在 Service 里修改了,一级缓存中相应的也就会被影响。由此可见,这个问题的核心原因也就很容易找到了。 问题复现 为了展示这个问题,咱还是简单复现一下场景吧。 工程搭建 咱使用 SpringBoot + mybatis-spring-boot-starter 快速构建出工程,此处 SpringBoot 版本为 2.2.8 , myb...