MyBatis 一级缓存避坑
MyBatis 一级缓存(MyBaits 称其为 Local Cache)无法关闭,但是有两种级别可选:
package org.apache.ibatis.session; /**
* @author Eduardo Macarron
*/
public enum LocalCacheScope {
SESSION, //session 级别的缓存
STATEMENT //statement 级别的缓存
}
1)session 级别的缓存
在同一个 sqlSession 内,对同样的查询将不再查询数据库,直接从缓存中。
验证代码:
public static void main(String[] args) throws IOException {
InputStream inputStream = new ClassPathResource("mybatis.xml").getInputStream();
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); UserDao mapper = sqlSession.getMapper(UserDao.class); System.out.println(mapper.get(1L));
System.out.println("-------------------");
System.out.println(mapper.get(1L));
}
输出:
日志输出可以看到,第一次查询通过数据库查询,第二次则没有,直接通过缓存读取。
坑:这种缓存策略有一个坑,在服务集群时就会出现问题。
假设现在有一个服务集群,有两个节点。
首先,两个节点都进行了同样的查询,两个节点都有自己的一级缓存,后续同样的查询,两个节点将不再查询数据库。
如果此时节点 1 执行了 update 语句,那么节点 1 的一级缓存会被刷新,而节点 2 的一级缓存不会改变。
2)statement 级别的缓存
避坑: 为了避免这个问题,可以将一级缓存的级别设为 statement 级别的,这样每次查询结束都会清掉一级缓存。MyBatis 源码如下:
在 MyBatis 的配置文件中,添加以下配置:
验证代码和上面的一样不变。
输出:
可以看到,即使是同样的查询,每次查询都是直接读取数据库了。
避坑完毕。
缓存是不可能不要缓存的,这个时候,就需要使用缓存中间件了,由缓存中间件管理缓存。
MyBatis 一级缓存避坑的更多相关文章
- Mybatis一级缓存和二级缓存总结
1:mybatis一级缓存:级别是session级别的,如果是同一个线程,同一个session,同一个查询条件,则只会查询数据库一次 2:mybatis二级缓存:级别是sessionfactory级别 ...
- Mybatis一级缓存和二级缓存 Redis缓存
一级缓存 Mybatis的一级缓存存放在SqlSession的生命周期,在同一个SqlSession中查询时,Mybatis会把执行的方法和参数通过算法生成缓存的键值,将键值和查询结果存入一个Map对 ...
- MyBatis 一级缓存与二级缓存
MyBatis一级缓存 MyBatis一级缓存默认开启,一级缓存为Session级别的缓存,在执行以下操作时一级缓存会清空 1.执行session.clearCache(); 2.执行CUD操作 3. ...
- MyBatis一级缓存引起的无穷递归
MyBatis一级缓存引起的无穷递归 引言: 最近在项目中参与了一个领取优惠劵的活动,当多个用户领取同一张优惠劵的时候,使用了数据库锁控制并发,起初的设想是:如果多个人同时领一张劵,第一个到达的人领取 ...
- mybatis一级缓存详解
mybatis缓存分为一级缓存,二级缓存和自定义缓存.本文重点讲解一级缓存 一:前言 在介绍缓存之前,先了解下mybatis的几个核心概念: * SqlSession:代表和数据库的一次会话,向用户提 ...
- 0065 MyBatis一级缓存与二级缓存
数据库中数据虽多,但访问频率却不同,有的数据1s内就会有多次访问,而有些数据几天都没人查询,这时候就可以将访问频率高的数据放到缓存中,就不用去数据库里取了,提高了效率还节约了数据库资源 MyBatis ...
- 关于mybatis 一级缓存引发的问题
场景: 由于在一个方法中存在多个不同业务操作 private void insertOrUpdateField(CompanyReport entity) { //计算并数据 calcReportDa ...
- MyBatis一级缓存(转载)
<深入理解mybatis原理> MyBatis的一级缓存实现详解 及使用注意事项 http://demo.netfoucs.com/luanlouis/article/details/41 ...
- MyBatis 一级缓存、二级缓存全详解(一)
目录 MyBatis 一级缓存.二级缓存全详解(一) 什么是缓存 什么是MyBatis中的缓存 MyBatis 中的一级缓存 初探一级缓存 探究一级缓存是如何失效的 一级缓存原理探究 还有其他要补充的 ...
随机推荐
- **深入了解lambda
之前已经了解过lambda了,但是在学习了闭包之后,我们有必要在探讨一下lambda(匿名函数). 匿名函数本质上就是一个函数,它所抽象出来的东西是一组运算. 它的使用场景就是:你在某处就真的只需要使 ...
- Spark中RDD的常用操作(Python)
弹性分布式数据集(RDD) Spark是以RDD概念为中心运行的.RDD是一个容错的.可以被并行操作的元素集合.创建一个RDD有两个方法:在你的驱动程序中并行化一个已经存在的集合:从外部存储系统中引用 ...
- ORA-00604: 递归 SQL 级别 1 出现错误 ORA-01000: 超出打开游标的最大数
有程序没关闭游标, --打开了哪些游标 select * from v$open_cursor 在open cursor之后一定要注意要close cursor(在store procedure里更应 ...
- Spark之 SparkSql、DataFrame、DataSet介绍
SparkSql SparkSql是专门为spark设计的一个大数据仓库工具,就好比hive是专门为hadoop设计的一个大数据仓库工具一样. 特性: .易整合 可以将sql查询与spark应用程序进 ...
- 第一个MFC实例:计算圆周长和圆面积
一.基于Microsoft MFC的编程方法 MFC是微软基础类库(Microsoft Foundation Class)的缩写.与API不同,MFC不是Windows操作系统的组成部分,而是微软公司 ...
- 53-C++ CH08 01
http://lx.lanqiao.cn/problem.page?gpid=T407 算法训练 C++ CH08 01 时间限制:1.0s 内存限制:256.0MB 问题描述 已 ...
- ServiceStack.redis用法
using System; using System.Collections.Generic; using ServiceStack.Redis; namespace SysBuild { class ...
- Django框架请求生命周期
先看一张图吧! 1.请求生命周期 - wsgi, 他就是socket服务端,用于接收用户请求并将请求进行初次封装,然后将请求交给web框架(Flask.Django) - 中间件,帮助我们对请求进行校 ...
- [GO]接口的转换
package main import "fmt" type Humaner interface { //子集 SayHi() } type Personer interface ...
- 【转】JAVA 并发编程-多个线程之间共享数据
原文地址:http://blog.csdn.net/hejingyuan6/article/details/47053409# 多线程共享数据的方式: 1,如果每个线程执行的代码相同,可以使用同一个R ...