Mybatis缓存机制介绍及避坑指南

本文会介绍mybatis缓存的工作原理,以及mybatis缓存导致的脏数据问题,以及如何避免脏数据的问题;

一级缓存:

基础知识:
1、在一个Session中,在Session级别的一级缓存下,mybatis会将读取到的数据放入一级缓存中,Session内所有的增删改操作都会使得该session的一级缓存失效;
2、在Session级别的一级缓存下,mybatis查询时会先从一级缓存中查询,查得到数据则直接返回,查不到再去db查,然后把从db查到的数据放入一级缓存中;
3、会被Executor持有,有两个级别,一个是session级别,即缓存内容在一个session范围内共享;一个是statement级别,即缓存内容只在一个statement内共享;
4、在Statement级别的一级缓存中,在查询方法的最后,都会判断到当前一级缓存的级别是Statement,然后清空缓存;

时序图:
在这里插入图片描述

一级缓存导致的脏数据问题:
假如会话A读取了一条数据并缓存在自己的一级缓存中,会话B修改了该条数据;由以上时序图可知,mybatis都是先去一级缓存查,如果查到了直接返回,查不到才去查数据库。这种情况下若会话A再一次读取该条数据,则会直接从自己的一级缓存中读取,而无法读取到最新的数据;(要区分清楚,这和mysql的可重复读隔离特性没关系,因为会话A未开启事务也会读到脏数据);

如何避免一级缓存的脏数据问题:
别用Session级别的一级缓存,用Statement级别的;

二级缓存:

基础知识:
1、 二级缓存的生命周期范围是namespace(即一个xml文件),可被多个Session共享
2、 一个xml可以引用别的namespace的Cache,这样它俩就共享同一个二级缓存;可通过在xml中进行如下配置来引用<cache-ref namespace="mapper.xxxMapper"/>
3、 会话必须提交事务了mybatis才能把读到的数据放入二级缓存中;
4、 增删改操作会使得其namespace的二级缓存失效;
5、 打开二级缓存后,mybatis查询的顺序为:二级缓存->一级缓存->db

工作流程图:
在这里插入图片描述

二级缓存导致的脏数据问题:
若在某个namespace A进行多表查询时,查到的数据会放入A的二级缓存中。若还有别namespace B更新了刚才A的多表查询中某个表,那么A是无法感知这个更新的,若再次进行同样的多表查询,将直接从二级缓存中查出来,而不是重新去db查出新数据;

如何避免二级缓存的脏数据问题:
关闭二级缓存;

参考:https://tech.meituan.com/2018/01/19/mybatis-cache.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值