首页 >文档 > MyBatis缓存mybatis缓存失效

MyBatis缓存mybatis缓存失效

MyBatis缓存失效问题是Java开发中的常见痛点,本文深度解析一级缓存和二级缓存的失效机制。从SqlSession隔离到Mapper配置,全面剖析增删改操作触发缓存清空的原理,并提供实战解决方案。学习如何正确配置flushCache属性、处理关联Mapper缓存同步、选择合适缓存策略,避免脏读和性能下降。掌握这些技巧能有效提升系统性能,同时为面试中"MyBatis缓存失效"问题提供完美答案。文中还包含清晰的执行流程图和配置示例,帮助开发者彻底理解MyBatis缓存工作机制,优化ORM框架使用体验。

MyBatis缓存mybatis缓存失效问题解析(程序员视角)

2025年Java面试宝典抢先下载 👈 提取码:9b3g

作为天天和ORM框架打交道的码农,今天咱唠唠面试常客——MyBatis缓存mybatis缓存失效问题。这玩意儿在实际项目和面试中出现的频率真不低,搞懂它能少踩很多坑!


🧠 Mybatis缓存机制回顾(必须搞清基础)

先得弄明白MyBatis的两级缓存结构,这是理解缓存失效mybatis缓存失效的前提:

  • 一级缓存(本地缓存):默认开启,作用域是SqlSession级别。同一个SqlSession里多次执行相同SQL,第二次开始直接走缓存。

    (MyBatis缓存执行流程图)

  • 二级缓存(全局缓存):需要手动配置开启,作用域是Mapper(namespace)级别。多个SqlSession共享同一个Mapper的缓存数据。生命周期更长。


🔥 为什么会出现Mybatis缓存失效问题?(高频面试考点)

面试官最爱揪着问的就是:“Mybatis缓存缓存失效的场景有哪些?” 结合实战经验,总结了这些关键点:

1️⃣ 一级缓存失效的经典场景

  • SqlSession不同:一级缓存绑死在SqlSession上。开新Session?缓存拜拜!
  • SqlSession相同,但执行了增删改(update/delete/insert):MyBatis为了保证数据一致性,只要执行了DML操作,自动清空当前SqlSession的一级缓存。这就是最典型的mybatis缓存失效触发点!
  • SqlSession相同,但手动调用clearCache():显式清空,缓存立马消失。
  • SqlSession相同,查询条件不同:SQL语句或参数变了,缓存不匹配当然用不了。
  • SqlSession关闭:Session没了,缓存自然跟着消亡。

2️⃣ 二级缓存失效的坑点(配置不当是主因)

  • 根本没开启二级缓存:这是最基础的!忘在mybatis-config.xml<setting name="cacheEnabled" value="true"/>或在Mapper XML写<cache/>标签?那二级缓存压根不存在。
  • 该Mapper的增删改操作被执行:和一级缓存类似,执行增删改会清空整个Mapper(namespace)的二级缓存,引发大规模缓存失效
  • 其他Mapper执行了更新关联数据的操作:如果B Mapper更新了A Mapper缓存所依赖的数据,而你没配置<cache-ref>或缓存共享机制,A的缓存不会自动失效,导致脏读!这需要特别注意。
  • 缓存策略不合理/缓存满被驱逐:如果缓存容量设置小或LRU策略激进,数据可能被提前踢出去造成失效
  • 事务提交问题:二级缓存生效是在SqlSession提交(commit())或关闭之后。如果你的事务没提交,查到的数据不会进二级缓存,下次查还是走DB。
  • 序列化问题:缓存对象没实现Serializable接口?那它根本存不进二级缓存(比如使用默认的PerpetualCache)。

🛠️ 如何解决或避免Mybatis缓存失效?(实战经验分享)

面对Mybatis缓存mybatis缓存失效,得对症下药:

  1. 明确需求,合理使用缓存:

    • 读远多于写的场景才值得开二级缓存。频繁更新就别折腾了,开了也总失效
    • 对实时性要求极高的数据(如库存),慎用二级缓存。
  2. 精细控制一级缓存作用域:

    • 在SqlSession内执行DML后,如果预期后续还需要重复查询相同数据,考虑是否要重新查询触发缓存重建(注意性能权衡)。
    • 对于只读操作,尽量复用同一个SqlSession(比如整合Spring时用@Transactional管理)。
  3. 正确配置和管理二级缓存:

    • 开启配置别遗漏mybatis-config.xml + Mapper XML的<cache/>标签。
    • 理解flushCache属性
      • <select>上设置flushCache="false"(默认),查询不刷新缓存。
      • <insert>/<update>/<delete>上设置flushCache="true"(默认),执行后刷新关联缓存(通常是本Mapper)。
    • 处理关联Mapper的缓存失效
      • 若Mapper A的缓存依赖Mapper B的数据,在B更新后,确保A的缓存被清除(可通过<cache-ref namespace="com.xxx.BMapper"/>引用,但谨慎使用,耦合高)。
      • 更灵活的方式:在B Mapper的更新操作中,编程式清除A Mapper的缓存(调用SqlSession.clearCache()需注意范围)。
    • 选择合适的缓存实现:默认的PerpetualCache是内存缓存。集成Redis、Ehcache等第三方缓存能提供分布式、持久化能力,减少本地缓存失效的困扰。记得配置序列化!
    • 设置合理的缓存参数<cache size="1024" eviction="LRU" .../>,根据数据量和访问模式调整。

📌程序员省💰贴士: 准备面试刷题买会员?通过 面试鸭返利网 找我下单,立返25元!能省则省才是合格码农!
面试鸭返利网返利信息


💡 面试官视角:怎么答“Mybatis缓存失效”问题

面试被问到Mybatis缓存mybatis缓存失效别慌,按这个思路捋:

  1. 简述两级缓存:“MyBatis有一级缓存(SqlSession级)和二级缓存(Mapper级)。一级缓存默认开,二级缓存需配置。”
  2. 重点分析失效场景:“一级缓存失效主要有:跨SqlSession、执行了增删改、手动清缓存、查询条件变。二级缓存失效原因包括:没开启配置、本Mapper或关联Mapper执行了增删改、事务未提交、序列化失败、缓存满被淘汰。”
  3. 结合解决方案:“避免失效可:1)根据业务选缓存级别;2)增删改后注意缓存状态;3)正确配置二级缓存及flushCache;4)关联Mapper更新时手动或配置联动清缓存;5)集成Redis等外部缓存。”
  4. 强调数据一致性:“核心问题是缓存和DB的数据一致性。MyBatis默认在写操作后失效相关缓存是保证一致性的重要手段,这也是缓存失效最常见的原因。”

搞懂Mybatis缓存mybatis缓存失效的原理和应对方案,无论是日常开发还是技术面试都能更从容。缓存是把双刃剑,用好了极大提升性能,用不好就是坑。建议大家多在本地环境模拟下各种失效场景,理解更深刻!需要最新面试题库的同学,别忘了上面分享的宝典资源和返利福利哦~

👉 访问 面试鸭返利网 (mianshiyafanli.com) 获取更多程序员福利!

如果你想获取更多关于面试鸭的优惠信息,可以访问面试鸭返利网面试鸭优惠网,了解最新的优惠活动和返利政策。

🎯 立即加入面试鸭会员 →

支付宝扫码领取1-8元无门槛红包

支付宝红包二维码