美文网首页
MyBatis 缓存 - 下:二级缓存

MyBatis 缓存 - 下:二级缓存

作者: DJN_ | 来源:发表于2018-11-26 14:18 被阅读0次

通过上篇文章我们已经知道,MyBatis 一级缓存的最大共享范围为 SqlSession,即一次会话中,而且有可能会因为缓存没更新而导致脏读问题。如果需要在多个 SqlSession 中共享缓存,那么就需要开启二级缓存。

SqlSession 的创建会借助 SqlSessionFactory,而 DefaultSqlSession 可由 DefaultSqlSessionFactory#openSession
获得,Executor 通过 Configuration#newExecutor 方法获得,该方法会检查 cacheEnabled 配置,开启就意味着启用二级缓存:

image.png

配置

MyBatis 配置文件通过如下配置开启:

<setting name="cacheEnabled" value="true"/>

一个 mapper 文件有唯一的 namespace (<mapper namespace="***">),在 mapper 文件中可通过 <cache/> 标签声明该 namespace 使用二级缓存。<cache-ref/> 可配置引用其他的命名空间,那么当前命名空间将与引用的命名空间使用同一个缓存(对于同一命名空间下的多表查询可借助该标签避免脏读问题)。<cache/> 标签有如下可选属性:

  • type:cache 类型,默认是 PerpetualCache
  • eviction: 回收的策略,比如 FIFO,LRU。
  • flushInterval: 配置一定时间自动刷新缓存,单位是毫秒。
  • size: 最多缓存对象的个数。
  • readOnly: 是否只读,若配置可读写,则需要对应的实体类能够序列化。
  • blocking: 若缓存中找不到对应的key,是否一直阻塞,直到有对应的数据进入缓存。

装饰器模式以及 TransactionalCacheManager

CachingExecutor 使用了装饰器模式,delegate 即为被装饰的 Executor 对象,tcm 为 TransactionalCacheManager 类型,tcm 管理了以 namespace 为单位的缓存。


先看 putObject 方法,内部调用了 getTransactionalCache 方法,该方法从 transactionalCaches 中取到了具体的 TransactionalCache,这里以 namespace 为单位的缓存作为 key,将这个 Cache 进行再包装的 TransactionalCache 作为值,TransactionalCache 处理了事务相关的一些特性。

缓存更新和获取

缓存的获取与一级缓存无异,都封装在 Executor#query 中:

image.png
区别是二级缓存通过 TransactionalCacheManager 来操作缓存。

在默认的设置中 SELECT(Executor#query) 语句不会刷新缓存,insert/update/delte (Executor#update)会刷新缓存。

  private void flushCacheIfRequired(MappedStatement ms) {
    Cache cache = ms.getCache();
    if (cache != null && ms.isFlushCacheRequired()) {      
      tcm.clear(cache);
    }
  }

调用 SqlSession#commit 二级缓存才会生效

image.png

已经知道在 Executor#query 方法中如果缓存没命中,那么从数据库中查询后会将数据新增到缓存中,但实际上此时还没有将数据放入缓存( HashMap),那 tcm.putObject 语句把数据放到了哪里呢 ?

tcm.putObject 会根据 Cache (作为 key)从 TransactionalCacheManager#transactionalCaches 中得到包装后的 TransactionalCache,再调用其 TransactionalCache#putObject 方法:

image.png
通过变量名就能知道 entriesToAddOnCommit 在调用 commit 时才会真正放入缓存的 HashMap 中,事实也是如此:
image.png

entriesMissedInCache 用于统计命中率。

参考文章:聊聊 MyBatis 缓存机制

相关文章

网友评论

      本文标题:MyBatis 缓存 - 下:二级缓存

      本文链接:https://www.haomeiwen.com/subject/vmwvqqtx.html