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.类要实现序列化

 

posted @ 2020-05-21 11:35  我是张某某  阅读(428)  评论(0)    收藏  举报