独角兽企业重金招聘Python工程师标准>>>
注:Mybatis的版本是3.5.0。
上一篇分析了一级缓存,这篇来分析二级缓存。
以下的内容,跳过了很多细节,可以去看这篇博客。
一级缓存只能在同一个SqlSession中共享,而二级缓存则可以在多个SqlSession中共享。
开启二级缓存,那么使用的是CachingExecutor和SimpleExecutor(不修改默认设置的情况下),如下List-1所示,SimpleExecutor是封装在CachingExecutor中的。
List-1
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {executorType = executorType == null ? defaultExecutorType : executorType;executorType = executorType == null ? ExecutorType.SIMPLE : executorType;Executor executor;if (ExecutorType.BATCH == executorType) {executor = new BatchExecutor(this, transaction);} else if (ExecutorType.REUSE == executorType) {executor = new ReuseExecutor(this, transaction);} else {executor = new SimpleExecutor(this, transaction);}if (cacheEnabled) {//将SimpleExecutor封装起来executor = new CachingExecutor(executor);}executor = (Executor) interceptorChain.pluginAll(executor);return executor;}
CachingExecutor使用了委托模式,其属性"Executor delegate",
List-2
package org.apache.ibatis.executor;....../*** @author Clinton Begin* @author Eduardo Macarron*/public class CachingExecutor implements Executor {private final Executor delegate;private final TransactionalCacheManager tcm = new TransactionalCacheManager();public CachingExecutor(Executor delegate) {this.delegate = delegate;delegate.setExecutorWrapper(this);}......
如下图1所示,CachingExecutor中使用的Cache是SynchronizedCache,它里面还封装了很多Cache,最终数据是存储在PerpetualCache中,是个HashMap。
图1 CachingExecutor中使用的Cache是SynchronizedCache
由于二级缓存Cache封装在SynchronizedCache中,所以对二级缓存的操作是线程安全的,SynchronizedCache的几乎每个方法上都加了Sychronized,这在实现线程安全的同时,也在一定程度上成了瓶颈,特别是对二级缓存操作的线程数量很多时。
在List-2中的属性tcm,这个是理解二级缓存的一个关键点。
private final TransactionalCacheManager tcm = new TransactionalCacheManager();
session1提交后,session2才能看到session1缓存的结果。
如果觉得《Mybatis之二级缓存简析》对你有帮助,请点赞、收藏,并留下你的观点哦!