Mybatis两级缓存,缓存原理介绍,面试题经典,可以完全背诵

一级缓存

一级缓存也叫本地缓存,在MyBatis中,一级缓存是在会话(SqlSession)层面实现的,这就说明一级缓存作用范围只能在同一个 SqlSession 中,跨 SqlSession 是无效的。
默认开启一级缓存.

二级缓存

二级缓存是mapper级别的缓存,如果多个SqlSession公用一个mapper文件,那么大家的第一次查询后的数据都会放在二级缓存中.二级缓存范围更大.
< setting name=“cacheEnabled” value=“true”/> 可以开启.

原理背诵

一级缓存是根据localcache去实现的,在Executor任意实现类取查询的时候都会执行父类 BaseExecutor 的 query 方法,在该方法里,首先会根据cachekey去查询缓存,如果没有,才会执行queryFromDatabase 方法,该方法会将查询结果放到缓存当中.
CacheKey 集合了 SQL 语句、SQL 参数、调用的 Mapper 方法名、SQL 分页参数、Environment 对象信息。

二级缓存是需要开启事务后才生效的,其底层是根据CachingExecutor 对象来实现的,该执行器里有一个TransactionalCacheManager 用来管理缓存,但其实也是使用了HashMap进行的一个缓存.在事务未提交之前,并不会真正缓存数据,而是先存储到一个临时属性,等事务提交之后才会真正存储到二级缓存。这么做的目的就是防止脏读。因为假如你在一个事务中修改了数据,然后去查询,这时候直接缓存了,那么假如事务回滚了呢?所以这里会先临时存储一下。在提交的方法sqlSession.commit() 中,我们会调用TransactionalCacheManager的commit方法,该方法里调用缓存管理器TransactionalCache来管理缓存,这里面有最重要的两个方法: flushPendingEntries 和 reset 两个方法, flushPendingEntries 方法负责把所有暂存区的内容刷新到缓存中,而 reset 方法则负责把本地暂存区清空, 同时把 clearOnCommit 置为 false。

对比

  1. 一级缓存是每个SqlSession独有的,因此如果在多线程环境下的写操作,一定会产生脏读问题,就是读到了另一个线程未提交的数据.而二级缓存是所有的SqlSession都可以共享一个缓存区域,与事务结合,可以解决脏读问题.
  2. 如果两个缓存都开启,只有在SqlSession关闭的时候,才会将数据保存在二级缓存中,如果按读取顺序,先读取二级缓存再读取一级缓存.
  3. 本人觉得,无论是一级缓存和二级缓存都是为了缓解数据库压力而生的,但是默认的一级缓存会存在脏读问题,需要使用集中式缓存将MyBatis的Cache接口实现,有一定的开发成本,而二级缓存又循环以事务开启,相对会变得复杂,直接使用Redis、Memcached等分布式缓存可能成本更低,安全性也更高。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值