Mybatis一级缓存和二级缓存
一级缓存是默认开启, sqlsession级别(不存在并发问题),缓存结构是hashmap key是cachkey对象
CacheKey key = createCacheKey(ms, parameter, rowBounds, boundSql);
value存放的是查询出来的对象
执行过程:
执行sql->先去看缓存是否命中-如果命中-直接返回
如果没命中-查询数据库-放到缓存中
执行增删改操作会clear缓存
sqlsession.close也会clear缓存
二级缓存需手动开启,mapper级别 (所以存在并发问题以及事务问题)
不同sqlsession针对同一个mapper进行查询 是可以命中缓存的
二级缓存在一级缓存之上,如果二级缓存开启的话,先去查询二级缓存是否命中,如果未命中,再去查询一级缓存
缓存结构:HashMap
存放的value不是对象 而是数据
执行过程:
执行sql->先去看缓存是否命中-如果命中-直接返回
如果没命中-查询数据库-放到缓存中
执行增删改操作会clear缓存
usercache(查询标签上 是否开启二级缓存 默认开启)
flushcache(增删改标签上 是否刷新二级缓存 默认开启
二级缓存事务问题:如果事务A修改记录,并存入缓存但是还没commit,此时事务B读取的就是脏数据
执行过程如下:

为了解决这个问题,可以为每个事务加一个独立的缓存,仍从共享缓存中查询,缓存未命中,则查询数据库,存储查询结果时,并不是把查询结果直接存储到共享缓存中,而是先存储到事务缓存中(独立缓存),当事务提交后,再把事务缓存中的缓存转到共享缓存中。过程如下


(mybatis并发事务问题只能解决脏读问题,目前不能解决不可重复读)
二级缓存缺点:底层是hashmap 不支持分布式 会产生脏读(某个服务器做了修改数据动作 但其他服务器没有 缓存没有被清除 就会产生脏数据)
所以一般不开启二级缓存 用redis代替
二级缓存开启:1.需要在数据源配置里配置cache-enabled=true 2.在类映射文件添加<cache/>标签 3.类要实现序列化

浙公网安备 33010602011771号