一级缓存

  • Mybatis的一级缓存存放在SqlSession的生命周期,在同一个SqlSession中查询时,Mybatis会把执行的方法和参数通过算法生成缓存的键值,将键值和查询结果存入一个Map对象中。
  • 如果同一个SqlSession中执行的方法和参数完全一致,那么通过算法会生成相同的键值,当Map缓存对象中已经存在改键值时,则会返回缓存中的对象。(一个SqlSession连续两次查询 得到的是同一个java对象)
  • 任何的insert update delete操作都会清空一级缓存(增删改任何记录都会清空当前SqlSession的缓存)。

Spring整合Mybatis的时候一级缓存的问题:

  在未开启事物的情况之下,每次查询,spring都会关闭旧的sqlSession而创建新的sqlSession,因此此时的一级缓存是没有启作用的

  在开启事物的情况之下,spring使用threadLocal获取当前资源绑定同一个sqlSession,因此此时一级缓存是有效的

Spring结合Mybatis一级缓存失效的问题

二级缓存

每个sqlSession都有自己的一级缓存,多个sqlSession共享二级缓存

Mybatis二级缓存可以理解为存在SqlSessionFactory的生命周期

开启二级缓存(还有全局的开启方式,这里就不多说了):

1.在对应的XXXMapper.XML添加如下代码

  <cache></cache>

2. 在对应的select标签上添加(测试了下 不加也行)

useCache="true"

二级缓存特点:

SqlSession1调用getMapper获取对象user1

SqlSession1调用getMapper获取对象user2

user1和user2是同一个实例(原理同一级缓存)

如果二级配置可读写的缓存 <cache readOnly="false"/>(顾名思义 可以写的缓存吗 就是我写这个对象 不影响你,两个实例),不同SqlSession之间通过序列化和反序列化来保证通过缓存获取数据。

当另外一个SqlSess2开始执行SQL时候,不会去查数据库 会利用SqlSession1的缓存

SqlSession2调用getMapper获取对象user1_

SqlSession2调用getMapper获取对象user2_

user1_和user2_就是反序列化得到的结果 是不同的实例

此时虽然只发出一个SQL 但是:user1==user2  user1_<>user2_<>user1

当 readOnly="true"的时候

<cache readOnly="true"/>

user1==user2==user1==user2

二级缓存坑的地方:

你在OrderMapper.XML 和 UserMapp.XML的文件 都操作了User表的话,

当你使用OrderMapper.XML的SQL更新User表的时候,其他的SeqSession在OrderMapper.XML可以查到User表最新的数据,但是在UserMapp.XML查不到最新的数据

原因就是 二级缓存是基于某个XXXMapper.xml,每个Mapper直接独立,所以 不同Mapper操作同一张表的时候  使用二级缓存会造成脏读

这也就是没什么人开启二级缓存的主要原因

Redis缓存一致性

Mybatis默认提供的缓存是基于Map实现的内存缓存,已经可以基本满足应用。但当需要缓存大量数据的时候可以使用Redis缓存数据库来保存Mybatis的二级缓存数据。

但MySQL和Redis是两个事物,不好做强一致性。

简单点:可以延时双删+过期时间保证最终一致性。

双删的原因是防止并发情况下 update_db的过程中 其他事物发现redis缓存是空 重新赋予了Redis的值 此时如果赋值 是错误的数据

第二次延时删除的原因是要考虑MySQL数据库主从同步的耗时(如果立即删除 有别的线程从MySQL的从库查到的数据放到Redis中 此时的从库可能是没同步的错误数据)

rm_redis
update_db
sleep xxx ms
rm_redis

Mybatis一级缓存和二级缓存 Redis缓存的更多相关文章

  1. 第04项目:淘淘商城(SpringMVC+Spring+Mybatis)【第七天】(redis缓存)

    https://pan.baidu.com/s/1bptYGAb#list/path=%2F&parentPath=%2Fsharelink389619878-229862621083040 ...

  2. 使用本地缓存快还是使用redis缓存好?

    使用本地缓存快还是使用redis缓存好? Redis早已家喻户晓,其性能自不必多说. 但是总有些时候,我们想把性能再提升一点,想着redis是个远程服务,性能也许不够,于是想用本地缓存试试!想法是不错 ...

  3. Django缓存机制以及使用redis缓存数据库

    目录 Django 配置缓存机制 缓存系统工作原理 Django settings 中 默认cache 缓存配置 利用文件系统来缓存 使用Memcache来缓存: 使用Local-memory来缓存: ...

  4. Hibernate一级缓存和二级缓存深度比较

    1.什么是缓存 缓存是介于应用程序和物理数据源之间,其作用是为了降低应用程序对物理数据源访问的频次,从而提高了应用的运行性能.缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据, ...

  5. Redis缓存穿透和缓存雪崩以及解决方案

    Redis缓存穿透和缓存雪崩以及解决方案 Redis缓存穿透和缓存雪崩以及解决方案缓存穿透解决方案布隆过滤缓存空对象比较缓存雪崩解决方案保证缓存层服务高可用性依赖隔离组件为后端限流并降级数据预热缓存并 ...

  6. SpringBoot集成Redis分布式锁以及Redis缓存

    https://blog.csdn.net/qq_26525215/article/details/79182687 集成Redis 首先在pom.xml中加入需要的redis依赖和缓存依赖 < ...

  7. django 常用方法总结 < 手写分页-上传头像-redis缓存,排行 ...>

    1.不使用自带模块<Paginator>的手写分页功能views.pydef post_list(request): page = request.GET.get('page', 1) # ...

  8. Azure Redis 缓存的 ASP.NET 会话状态提供程序

    Azure Redis Cache 提供了一个会话状态提供程序,你可以使用其在缓存中(而不是内存中或在 SQL Server 数据库中)存储会话状态.要使用缓存会话状态提供程序,先首先配置缓存,然后使 ...

  9. 使用nginx+lua脚本读写redis缓存

    配置 新建spring boot项目增加redis配置 <dependency> <groupId>org.springframework.boot</groupId&g ...

随机推荐

  1. JS中的Number数据类型详解

    Number数据类型 Number类型使用IEEE754格式来表示整数和浮点值,这也是0.2 + 0.3不等于0.5的原因, 最基本的数值类型字面量格式是十进制整数 var a = 10; 1. 浮点 ...

  2. ViewMode

    一.ViewMode 实现使用场景-Model枚举的情景下, 注意:枚举声明在后台的时候,需要渲染界面,页面表格使用 Bootstrap Table插件-事先通过ajax 渲染(数据库读取值1.2.3 ...

  3. gvfs错误导致tilda和thunar启动缓慢问题的解决

    tilda是一个非常轻便的下拉终端,但是安装之后启动发现要过十几秒才会出现界面.命令行启动发现报错如下: 用这条信息到处搜索也找不到有用的解答. 后来终于发现这是一个dbus超时的问题,虽然原因和这个 ...

  4. Spark 读取HBase数据

    Spark1.6.2 读取 HBase 1.2.3 //hbase-common-1.2.3.jar //hbase-protocol-1.2.3.jar //hbase-server-1.2.3.j ...

  5. poj2689 Prime Distance(素数区间筛法)

    题目链接:http://poj.org/problem?id=2689 题目大意:输入两个数L和U(1<=L<U<=2 147 483 647),要找出两个相邻素数C1和C2(L&l ...

  6. CS184.1X 计算机图形学导论(第五讲)

    一.观察:正交投影 1.特性:保持平行线在投影后仍然是平行的 2.一个长方体,对处在只有深度不同的位置上的同一物体来说,它的大小不会改变. 3.透视投影:平行线在远处会相交(例如铁轨) 4.glOrt ...

  7. 《Spring Boot实战》笔记 (六章)

    6.1 基本配置 ........................................................................................... ...

  8. JAVA中位数排序

    package quickSort; public class QuickSort { private static int count; /** * 测试 * @param args */ publ ...

  9. redis开发规范阿里云

    一.键值设计 1.key名设计 1) 可读性和可管理性:  以业务名或数据库名为前缀,以防key冲突,用冒号分隔,比如业务名:表名:ID 2)简洁性: 保证语义的前提下,控制key的长度,当key较多 ...

  10. html中 的method=post和method=get的区别

    1. get是从服务器上获取数据,post是向服务器传送数据. 2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到.post是通过 ...