Hibernate一级缓存与二级缓存的区别

半腔热情 提交于 2020-02-25 01:46:25

一级缓存:
  就是Session级别的缓存。一个Session做了一个查询操作,它会把这个操作的结果放在一级缓存中。
  如果短时间内这个session(一定要同一个session)又做了同一个操作,那么hibernate直接从一级缓存中拿,而不会再去连数据库,取数据。
  它是内置的事务范围的缓存不能被卸载
二级缓存:
  就是SessionFactory级别的缓存。顾名思义,就是查询的时候会把查询结果缓存到二级缓存中。
  如果同一个sessionFactory创建的某个session执行了相同的操作,hibernate就会从二级缓存中拿结果,而不会再去连接数据库。
  这是可选的插件式的缓存,在默认情况下,SessionFactory不会启用这个插件。
  可以在每个类或每个集合的粒度上配置缓存适配器用于把具体的缓存实现软件与Hibernate集成。

严格意义上说,SessionFactory缓存分为两类:内置缓存和外置缓存。我们通常意义上说的二级缓存是指外置缓存。

内置缓存与session级别缓存实现方式相似。前者是SessionFactory对象的一些集合属性包含的数据,后者是指Session的一些集合属性包含的数据

SessionFactory的内置缓存中存放了映射元数据和预定义SQL语句。
  映射元数据是映射文件中数据的拷贝;
  而预定义SQL语句是在Hibernate初始化阶段根据映射元数据推导出来。
SessionFactory的内置缓存是只读的,应用程序不能修改缓存中的映射元数据和预定义SQL语句,因此SessionFactory不需要进行内置缓存与映射文件的同步。

Hibernate的这两级缓存都位于持久化层,存放的都是数据库数据的拷贝。

缓存的两个特性:
  缓存的范围
  缓存的并发访问策略

1、缓存的范围
  决定了缓存的生命周期以及可以被谁访问。缓存的范围分为三类。
  事务范围
  进程范围
  集群范围
  注:
    对大多数应用来说,应该慎重地考虑是否需要使用集群范围的缓存,因为访问的速度不一定会比直接访问数据库数据的速度快多少。
    事务范围的缓存是持久化层的第一级缓存,通常它是必需的;进程范围或集群范围的缓存是持久化层的第二级缓存,通常是可选的。

2、缓存的并发访问策略
  当多个并发的事务同时访问持久化层的缓存的相同数据时,会引起并发问题,必须采用必要的事务隔离措施。

  在进程范围或集群范围的缓存,即第二级缓存,会出现并发问题。
  因此可以设定以下四种类型的并发访问策略,每一种策略对应一种事务隔离级别。
  事务型并发访问策略是事务隔离级别最高,只读型的隔离级别最低。事务隔离级别越高,并发性能就越低。

  A 事务型:仅仅在受管理环境中适用。它提供了Repeatable Read事务隔离级别。
      对于经常被读但很少修改的数据,可以采用这种隔离类型,因为它可以防止脏读和不可重复读这类的并发问题。
  B 读写型:提供了Read Committed事务隔离级别。仅仅在非集群的环境中适用。
      对于经常被读但很少修改的数据,可以采用这种隔离类型,因为它可以防止脏读这类的并发问题。
  C 非严格读写型:不保证缓存与数据库中数据的一致性。
      如果存在两个事务同时访问缓存中相同数据的可能,必须为该数据配置一个很短的数据过期时间,从而尽量避免脏读。
      对于极少被修改,并且允许偶尔脏读的数据,可以采用这种并发访问策略。
  D 只读型:对于从来不会修改的数据,如参考数据,可以使用这种并发访问策略。

什么样的数据适合存放到第二级缓存中?
  1、很少被修改的数据
  2、不是很重要的数据,允许出现偶尔并发的数据
  3、不会被并发访问的数据
  4、参考数据

不适合存放到第二级缓存的数据?
  1、经常被修改的数据
  2、财务数据,绝对不允许出现并发
  3、与其他应用共享的数据。

Hibernate的二级缓存策略的一般过程如下:
  1) 条件查询的时候,总是发出一条select * from table_name where …. (选择所有字段)这样的SQL语句查询数据库,一次获得所有的数据对象。
  2) 把获得的所有数据对象根据ID放入到第二级缓存中。
  3) 当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;查不到,再查询数据库,把结果按照ID放入到缓存。
  4) 删除、更新、增加数据的时候,同时更新缓存。

注:
  Hibernate的二级缓存策略,是针对于ID查询的缓存策略,对于条件查询则毫无作用。为此,Hibernate提供了针对条件查询的Query缓存。

Query缓存策略的过程如下:
  1) Hibernate首先根据这些信息组成一个Query Key,Query Key包括条件查询的请求一般信息:SQL, SQL需要的参数,记录范围(起始位置rowStart,最大记录个数maxRows),等。
  2) Hibernate根据这个Query Key到Query缓存中查找对应的结果列表。如果存在,那么返回这个结果列表;如果不存在,查询数据库,获取结果列表,把整个结果列表根据Query Key放入到Query缓存中。
  3) Query Key中的SQL涉及到一些表名,如果这些表的任何数据发生修改、删除、增加等操作,这些相关的Query Key都要从缓存中清空。

 参考文章:
http://hi.baidu.com/minordragon/blog/item/8043ea621f330cdae7113af4.html 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!