• 一二级缓存


    最近想给系统(spring-boot + Mybatis)弄一个二级缓存,看了一些资料,就总结一下

    一级缓存
      一级缓存是SqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构用于存储缓存数据。
      不同的sqlSession之间的缓存数据区域是互相不影响的。也就是只能作用在同一个sqlSession中,不同的sqlSession中的缓存是互相不能读取的。
     
    一级缓存的工作原理:
      用户发起查询请求,查找某条数据,sqlSession先去缓存中查找,是否有该数据,如果有,读取;
      如果没有,从数据库中查询,并将查询到的数据放入一级缓存区域,供下次查找使用。
      但sqlSession执行commit,即增删改操作时会清空缓存。这么做的目的是避免脏读。
      如果commit不清空缓存,会有以下场景:A查询了某商品库存为10件,并将10件库存的数据存入缓存中,之后被客户买走了10件,数据被delete了,但是下次查询这件商品时,并不从数据库中查询,而是从缓存中查询,就会出现错误。
     
    既然有了一级缓存,那么为什么还需要二级缓存呢?
     
      二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。二级缓存的作用范围更大。
      还有一个原因,实际开发中,MyBatis通常和Spring进行整合开发。Spring将事务放到Service中管理,对于每一个service中的sqlsession是不同的,这是通过mybatis-spring中的org.mybatis.spring.mapper.MapperScannerConfigurer创建sqlsession自动注入到service中的。 每次查询之后都要进行关闭sqlSession,关闭之后数据被清空。所以spring整合之后,如果没有事务,一级缓存是没有意义的。
      而Spring和MyBatis整合时, 每次查询之后都要进行关闭sqlSession,关闭之后数据被清空。所以spring整合之后,如果没有事务,一级缓存是没有意义的。
      那么如果开启二级缓存,关闭sqlsession后,会把该sqlsession一级缓存中的数据添加到namespace的二级缓存中。这样,缓存在sqlsession关闭之后依然存在。
     
    总结:
      对于查询多commit少且用户对查询结果实时性要求不高,此时采用mybatis二级缓存技术降低数据库访问量,提高访问速度。 
      但不能滥用二级缓存,二级缓存也有很多弊端,从MyBatis默认二级缓存是关闭的就可以看出来。
      二级缓存是建立在同一个namespace下的,如果对表的操作查询可能有多个namespace,那么得到的数据就是错误的。
     
    举个简单的例子:
      订单和订单详情,orderMapper、orderDetailMapper。在查询订单详情时我们需要把订单信息也查询出来,那么这个订单详情的信息被二级缓存在orderDetailMapper的namespace中,这个时候有人要修改订单的基本信息,那就是在orderMapper的namespace下修改,他是不会影响到orderDetailMapper的缓存的,那么你再次查找订单详情时,拿到的是缓存的数据,这个数据其实已经是过时的。
     
    根据以上,想要使用二级缓存时需要想好两个问题:
      1)对该表的操作与查询都在同一个namespace下,其他的namespace如果有操作,就会发生数据的脏读。
      2)对关联表的查询,关联的所有表的操作都必须在同一个namespace。
     
     
    其实一二级缓存都有可能出现脏读问题,使用时需考虑好相关设计。

    Mybatis二级缓存适合场景有限。

      一方面缓存保存在namespace空间下,比较适合缓存单表的数据缓存,不适合存在多表联合的情况。

      另一方面缓存的数据条数有限制。

     

    hibernate和mybatis缓存方面比较

    相同:

      1.都分为两级缓存,一级缓存和二级缓存,一级缓存都是session事务级别的,在一个事务中有效,事务执行完后缓存失效

      2.一般用户不需要干涉一级缓存,默认一级缓存时开启的

      3.二级缓存都可以自定义配置,手动设置开启或者关闭

      4.mybatis可以针对mapper中某一个statement设置是否使用二级缓存

      5.二级缓存都可以通过配置使用EHCache(可持久化到硬盘)

    不同:

      1.hibernate的二级缓存时应用进程级别的,整个应用进程查询相同的sql时会使用二级缓存中的数据;mybatis是相同namespace下的mapper文件中的sql缓存,可以让多个sqlSession共享,但不是应用程序级别

      2.mybatis的相同namespace下的mapper中如果有增删改的操作,会自动清空二级缓存的内容

     
     
    参考:
     

    共同学习,共同进步,若有补充,欢迎指出,谢谢!

  • 相关阅读:
    fenby C语言P21
    fenby C语言 P20
    fenby C语言 P19
    fenby C语言 P18
    fenby C语言 P17
    fenby C语言 P16
    fenby C语言 P15
    fenby C语言 P14
    Python学习之路:subprocess模块和面向对象
    Python学习之路:XML模块
  • 原文地址:https://www.cnblogs.com/dengguangxue/p/11255107.html
Copyright © 2020-2023  润新知