MyBatis功能点一:二级缓存cache
对于Mybatis缓存分作用域等维度区别一、二级缓存特点如下图:

分析缓存源码首先得找到缓存操作的入口:前面已经分析,sqlsesion.close()仅对一级缓存有影响,而update等对一/二级缓存均有影响。那从session为入口分析一级缓存,从mapper分析二级缓存。
对于缓存的作用域,之前文章五、MyBatis缓存初体验 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中已经验证,下面主要从底层数据结构这个维度理解一二级缓存。既然都是基于Perpetualcache的HashMap本地缓存,那么通过调试跟踪到其源码所在位置分析:

PerpetualCache是对JUC中Cache接口的实现,其核心结构为命名为cache的Map<Object, Object>;所以缓存实际就是一个附带id的HashMap。实际上是不是只要实现了JUC中Cache接口均可以作为Mybatis备用缓存???当然可以,可参考MyBatis缓存Cache包 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)。
一级缓存
跟踪调试仅使用一级缓存的代码,调试信息发现,
,
即可知SimpleExectutor或其上级父类中对一级缓存进行处理,跟踪调试信息,可得如下调用链(查看MyBatis中执行器Executor框架 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)):
一级缓存功能由BaseExecutor类实现,即意味着每个实际执行器都具有这一级的功能。

那么其具体应用逻辑为何?查看源码如下:

从源码分析可得:如果设置了每次查询都清缓存,那么每次查询清缓存。同时查询之前判断localCache中是否有当前查询statement.id的相应数据,如果有则直接从一级缓存中获取结果,否则进行查询数据库的操作。
二级缓存
二级缓存的作用范围是一个命名空间(即一个映射文件或多个mapper文件同一个命名空间),而且可以实现多个命名空间共享一个缓存。跟踪二级缓存,其建立在mapper配置文件解析过程中即建立,而不是在opensession中。

二级缓存默认开启,如取消采用如下配置:
<settings>
<setting name="cacheEnabled" value="false"/>
</settings>
注解方式在mapper接口中使用如下注解,二级缓存生效,否则开启亦不生效。同理在mapper.xml文件中也需配置<cache></cache>表示二级缓存生效
通过注解
开启二级缓存,查看注解源码

可知默认使用PerpetualCache的实现,通过implementation属性,说明二级缓存是可配置的。可以配置用户需要使用的第三方或自定义缓存,比如redis。
那二级缓存是如何工作的?我们开启二级缓存通过调试查看源码,如下:

可知CachingExecutor中首先查询二级缓存,如果查询结果为空则业务逻辑有simpleExecutor处理即一级缓存的使用逻辑。
开篇提到,sqlSession.close仅对一级缓存清空二级缓存无影响,以及update等操作对一二级缓存均清空,那么通过close和update源码分别来证实:

分析CachingExecutor中close的业务逻辑:

首先处理二级缓存rollback或者commit,再处理一级缓存赋值null。所以close操作会清空一级缓存,二级缓存强制回退或者提交数据。

分析CachingExecutor中update的业务逻辑,显然与close方法不同,如下:
在上面分析过程中都遇到了CachingExecutor的一个属性,tcm——啥玩意?TransactionalCacheManager

MyBatis将Cache,TransactionalCache做了映射,而不是和一级缓存保存一致,直接使用,这是为什么呢?下面附源码两张:


第一张图说明一级缓存直接在executor中活动,即作用范围为session;第二张图说明二级缓存在MappedStatement中活动,作用范围跨session了。同样证实了开篇提到的cache作用范围。也因为二级缓存的作用范围跨session,可以同时被多个session同时获取就出现了线程安全的问题,导致脏读问题。为了解决这一问题,就有了TransactionalCache及其Manager——就是tcm对应类。

从其类图中,可以直观的发现其增加了读写锁相关的功能。
MyBatis功能点一:二级缓存cache的更多相关文章
- mybatis 使用redis实现二级缓存(spring boot)
mybatis 自定义redis做二级缓存 前言 如果关注功能实现,可以直接看功能实现部分 何时使用二级缓存 一个宗旨---不常变的稳定而常用的 一级是默认开启的sqlsession级别的. 只在单表 ...
- Mybatis整合Redis实现二级缓存
Mybatis集成ehcache . 为什么需要缓存 拉高程序的性能 . 什么样的数据需要缓存 很少被修改或根本不改的数据 业务场景比如:耗时较高的统计分析sql.电话账单查询sql等 . ehcac ...
- mybatis精讲(六)--二级缓存
目录 简介 配置 源码 CachingExecutor 自定义二级缓存 # 加入战队 微信公众号 简介 上一章节我们简单了解了二级缓存的配置.今天我们详细分析下二级缓存以及为什么不建议使用二级缓存. ...
- myBatis源码解析-二级缓存的实现方式
1. 前言 前面近一个月去写自己的mybatis框架了,对mybatis源码分析止步不前,此文继续前面的文章.开始分析mybatis一,二级缓存的实现.附上自己的项目github地址:https:// ...
- SSM+redis整合(mybatis整合redis做二级缓存)
SSM:是Spring+Struts+Mybatis ,另外还使用了PageHelper 前言: 这里主要是利用redis去做mybatis的二级缓存,mybaits映射文件中所有的select都会刷 ...
- java:Mybatis框架3(二级缓存,延时和积极加载,SSI(Ibatis)集成,SSM集成)
1.二级缓存: 需要导入二级缓存jar包: mybatis03: ehcache.xml: <ehcache xmlns:xsi="http://www.w3.org/2001/XML ...
- Mybatis架构原理(二)-二级缓存源码剖析
Mybatis架构原理(二)-二级缓存源码剖析 二级缓存构建在一级缓存之上,在收到查询请求时,Mybatis首先会查询二级缓存,若二级缓存没有命中,再去查询一级缓存,一级缓存没有,在查询数据库; 二级 ...
- mybatis结合redis实战二级缓存(六)
之前的文章中我们意见分析了一级缓存.二级缓存的相关源码和基本原理,今天我们来分享下了mybatis二级缓存和redis的结合,当然mybatis二级缓存也可以和ehcache.memcache.OSC ...
- SpringMVC + MyBatis + Mysql + Redis(作为二级缓存) 配置
2016年03月03日 10:37:47 标签: mysql / redis / mybatis / spring mvc / spring 33805 项目环境: 在SpringMVC + MyBa ...
随机推荐
- 使用Redis分布式锁控制请求串行处理
1.需求背景 在一些写接口的场景下,由于一些网络因素导致用户的表单重复提交,就会在相邻很短的时间内,发出多个数据一样的请求.后台接口的幂等性保证一般都是先检查数据的状态,然后决定是否进行执行写入操作, ...
- 打印十字码 DataMatrix
nuget 安装 DataMatrix.net //示例 DmtxImageEncoder Die = new DmtxImageEncoder(); DataMatrix.net.DmtxImage ...
- 【刷题-LeetCode】239. Sliding Window Maximum
Sliding Window Maximum Given an array nums, there is a sliding window of size k which is moving from ...
- redis如何避免释放锁时把别人的锁释放掉
场景:假如线程A获取分布式锁进入方法A,由于某种原因Hang住了 到了指定时间释放锁,这个时候线程B进入得到锁,这个时候线程B很顺利完成业务逻辑操作,然后释放掉锁,就在这个时候线程A开始继续往下执行代 ...
- golang中的标准库time
时间类型 time.Time类型表示时间.我们可以通过time.Now()函数获取当前的时间对象,然后获取时间对象的年月日时分秒等信息.示例代码如下: func main() { current := ...
- java-包与包之间的访问
1 package face_package; 2 3 import face_packagedemoA.DemoA; 4 5 /* 包(package) 6 * 1,对类文件进行分类管理. 7 * ...
- centos下python2升级为python3
1.下载 下载地址 https://www.python.org/downloads/release/python-353/ 选择"Gzipped source tarball"这 ...
- mysql加强(4)~多表查询
mysql加强(4)~多表查询:笛卡尔积.消除笛卡尔积操作(等值.非等值连接),内连接(隐式连接.显示连接).外连接.自连接 一.笛卡尔积 1.什么是笛卡尔积: 数学上,有两个集合A={a,b},B= ...
- Linux 配置 mycat 和 分库分表配置。
Linux 如何配置mycat? 3.配置mycat 3.1.规定linux的用户名和全名不能叫mycat!!!否则mycat会不生效(原因是影响整个linux系统的环境变量导致mycat的配置环境变 ...
- vivo 评论中台的流量及数据隔离实践
一.背景 vivo评论中台通过提供评论发表.点赞.举报.自定义评论排序等通用能力,帮助前台业务快速搭建评论功能并提供评论运营能力,避免了前台业务的重复建设和数据孤岛问题.目前已有vivo短视频.viv ...