MyBatis 的一级缓存和二级缓存
  0ph59blLrzgC 2023年11月02日 47 0

1、前言

排查生产问题,报错接口中的同一条sql执行时间不同。

2、一级缓存

一级缓存是默认开启的,在一个sqlSession会话里面的所有 查询 操作都会保存到缓存中。如果同一个sqlSession会话中 2个查询中间有一个 insert 、update或delete 语句,那么之前查询的所有缓存都会清空;

2.1、一级缓存的工作原理

MyBatis 的一级缓存和二级缓存_一级缓存

用户发起查询请求,查找某条数据,sqlSession 先去缓存中查找,是否有该数据,如果有,读取; 如果没有,从数据库中查询,并将查询到的数据放入一级缓存区域,供下次查找使用。

但 sqlSession 执行commit,即增删改操作时会清空缓存。这么做的目的是避免脏读。

2.2、一级缓存生效条件

一级缓存要生效,必须满足以下条件条件:

  • 必须是相同的会话
  • 必须是同一个 mapper,即同一个 namespace
  • 必须是相同的 statement,即同一个 mapper 中的同一个方法
  • 必须是相同的 SQL 和参数
  • 查询语句中间没有执行sqlSession.close() 方法
  • 查询语句中间没有执行 insert/update/delete 方法(无论变动记录是否与缓存数据有无关系)

3、二级缓存

二级缓存是 SqlSessionFactory 级别,通过 SqlSessionFactory 创建SqlSession 查询的结果会被缓存。 此后若再次执行相同的查询,结果就会从缓存中获取。

3.1、二级缓存的流程图

MyBatis 的一级缓存和二级缓存_二级缓存_02

  • 开启二级缓存后,用户查询时,会先去二级缓存中找,找不到了再去一级缓存中找;
  • 一级缓存也没有查询到,则查询数据库;
  • 当sqlSession会话提交或者关闭时,一级缓存的数据会刷新到二级缓存中;


3.2 二级缓存生效条件

  • 当会话提交或关闭之后才会填充二级缓存
  • 必须是同一个 mapper,即同一个命名空间
  • 必须是相同的 statement,即同一个 mapper 中的同一个方法
  • 必须是相同的 SQL 语句和参数
  • 如果 readWrite=true(默认就是true),实体对像必须实现 Serializable 接口

3.3、开启二级缓存

  1. mybatis-plus.configuration.cache-enabled = true
  2. <cache eviction="FIFO" flushInterval="60000" readOnly="false" size="1024"> </cache>

<cache eviction="FIFO" // 回收策略为先进先出

flushInterval="60000" // 自动刷新时间60s

size="512" // 最多缓存512个引用对象

readOnly="true"/> // 只读

  1. POJO 类实现 Serializable 接口

4、一、二级缓存总结

  1. 二级缓存是 mapper 级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。二级缓存的作用范围更大。
  2. 实际开发中,MyBatis 通常和 Spring 进行整合开发。 Spring 将事务放到 Service 中管理,对于每一个 service 中的 sqlsession 是不同的, 这是通过 mybatis-spring 中的 org.mybatis.spring.mapper.MapperScannerConfigurer 创建 sqlsession 自动注入到 service 中的。 每次查询之后都要进行关闭 sqlSession ,关闭之后数据被清空。 所以 spring 整合之后,如果没有事务,一级缓存 是没有意义的。

5、使用原则(避坑)

  • 只能在一个命名空间下使用二级缓存 由于二级缓存中的数据是基于namespace的,即不同 namespace 中的数据互不干扰。 在多个namespace中存在对同一个表的操作,那么这多个namespace中的数据可能就会出现不一致现象。
  • 在单表上使用二级缓存 如果一个表与其它表有关联关系,那么就非常有可能存在多个 namespace 对同一数据的操作。 而不同 namespace 中的数据相互干扰,所以就有可能出现多个 namespace 中的数据不一致现象。
  • 查询多于修改时使用二级缓存 在查询操作远远多于增删改操作的情况下可以使用二级缓存。因为任何增删改操作都将刷新二级缓存,对二级缓存的频繁刷新将降低系统性能。


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  biE3E3UjTjeg   2024年01月22日   36   0   0 SQLSQL
  eEsPR9IZLNNM   2023年12月24日   63   0   0 sqlJavaSQLJava
0ph59blLrzgC
作者其他文章 更多