一级缓存源码分析

一级缓存触发流程:
在这里插入图片描述

我们注意到这里一级缓存使用的是map结构来存储缓存,为何不用ConcurrentHashMap呢,因为sqlSession本身不是线程安全的,它不线程安全是由于JDBC的Connection对象本身也不是线程安全的,所以既然都不安全了,所以这里也没必要做线程安全的map结构。
我们来看看缓存的key里面有什么:
在这里插入图片描述
我们可以看到,有statementid,分页条件,查询语句内容,查询参数,环境(environment的id),这个也对应了缓存的命中场景的内容。

一级缓存的判断主要发生在BaseExecutor的query方法中,如下所示:
若找不到缓存则去查询数据查询。

题外话:什么时候清空缓存?
调用BaseExecutor的update方法的时候:

  public int update(MappedStatement ms, Object parameter) throws SQLException {
    ErrorContext.instance().resource(ms.getResource()).activity("executing an update").object(ms.getId());
    if (closed) {
      throw new ExecutorException("Executor was closed.");
    }
    clearLocalCache();
    return doUpdate(ms, parameter);
  }

调用BaseExecutor.query,判断是否第一次查询的时候,且配置了flushCache为true,即调用:

if (queryStack == 0 && ms.isFlushCacheRequired()) {
      clearLocalCache();
    }

调用BaseExecutor.query,查询后,缓存的作用域不是STATEMENT,这里必须要是第一次查询,子查询是不会清空缓存的。

if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {
        // issue #482
        clearLocalCache();
      }

调用BaseExecutor.commit或者rollback:

public void commit(boolean required) throws SQLException {
    if (closed) {
      throw new ExecutorException("Cannot commit, transaction is already closed");
    }
    clearLocalCache();
    flushStatements();
    if (required) {
      transaction.commit();
    }
  }
public void rollback(boolean required) throws SQLException {
    if (!closed) {
      try {
        clearLocalCache();
        flushStatements(true);
      } finally {
        if (required) {
          transaction.rollback();
        }
      }
    }
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值