在向你们详细介绍Hibernate二级缓存以前,首先让你们了解下一级缓存,而后全面介绍Hibernate二级缓存。算法
Hibernate中提供了两级Cache,第一级别的缓存是Session级别的缓存,它是属于事务范围的缓存。这一级别的缓存由hibernate管理的,通常状况下无需进行干预;第二级别的缓存是SessionFactory级别的缓存,它是属于进程范围或群集范围的缓存。这一级别的缓存能够进行配置和更改,而且能够动态加载和卸载。 Hibernate还为查询结果提供了一个查询缓存,它依赖于第二级缓存。数据库
一. 一级缓存和二级缓存的比较:缓存
第一级缓存 第二级缓存 存放数据的形式相互关联的持久化对象 对象的散装数据 缓存的范围事务范围,并发
每一个事务都有单独的第一级缓存进程范围或集群范围,ide
缓存被同一个进程或集群范围内的全部事务共享并发访问策略因为每一个事务都拥有单独的第一级缓存,性能
不会出现并发问题,无需提供并发访问策略因为多个事务会同时访问第二级缓存中相同数据,hibernate
所以必须提供适当的并发访问策略,来保证特定的事务隔离级别数据过时策略没有提供数据插件
过时策略。处于一级缓存中的对象永远不会过时,除非应用程序显式清空缓存或者清除特定的对象必须提供数据过时策略,如基于内存的缓存中的对象的最大数目,容许对象处于缓存中的最长时间,以及容许对象处于缓存中的最长空闲时间物理存储介质内存内存和硬盘。对象的散装数据首先存放在基于内存的缓存中,当内存中对象的数目达到数据过时策略中指定上限时,就会把其他的对象写入基于硬盘的缓存中。缓存的软件实如今Hibernate的Session的实现中包含了缓存的实现由第三方提供,Hibernate仅提供了缓存适配器(CacheProvider)。用于把特定的缓存插件集成到Hibernate中。启用缓存的方式只要应用程序经过Session接口来执行保存、更新、删除、加载和查询数据库数据的操做,Hibernate就会启用第一级缓存,把数据库中的数据以对象的形式拷贝到缓存中,对于批量更新和批量删除操做,若是不但愿启用第一级缓存,能够绕过Hibernate API,直接经过JDBC API来执行指操做。用户能够在单个类或类的单个集合的粒度上配置第二级缓存。对象
若是类的实例被常常读但不多被修改,就能够考虑使用第二级缓存。只有为某个类或集合配置了第二级缓存,Hibernate在运行时才会把它的实例加入到第二级缓存中。用户管理缓存的方式第一级缓存的物理介质为内存,因为内存容量有限,必须经过恰当的检索策略和检索方式来限制加载对象的数目。Session的 evit()方法能够显式清空缓存中特定对象,但这种方法不值得推荐。第二级缓存的物理介质能够是内存和硬盘,所以第二级缓存能够存放大量的数据,数据过时策略的maxElementsInMemory属性值能够控制内存中的对象数目。管理第二级缓存主要包括两个方面:选择须要使用第二级缓存的持久类,设置合适的并发访问策略:选择缓存适配器,设置合适的数据过时策略。接口
二. 一级缓存的管理:
当应用程序调用Session的save()、update()、savaeOrUpdate()、get()或load(),以及调用查询接口的 list()、iterate()或filter()方法时,若是在Session缓存中还不存在相应的对象,Hibernate就会把该对象加入到第一级缓存中。当清理缓存时,Hibernate会根据缓存中对象的状态变化来同步更新数据库。 Session为应用程序提供了两个管理缓存的方法: evict(Object obj):从缓存中清除参数指定的持久化对象。 clear():清空缓存中全部持久化对象。
三. Hibernate二级缓存的管理:
1. Hibernate二级缓存策略的通常过程以下:
1) 条件查询的时候,老是发出一条select * from table_name where …. (选择全部字段)这样的SQL语句查询数据库,一次得到全部的数据对象。
2) 把得到的全部数据对象根据ID放入到第二级缓存中。
3) 当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;查不到,若是配置了二级缓存,那么从二级缓存中查;查不到,再查询数据库,把结果按照ID放入到缓存。
4) 删除、更新、增长数据的时候,同时更新缓存。
Hibernate二级缓存策略,是针对于ID查询的缓存策略,对于条件查询则毫无做用。为此,Hibernate提供了针对条件查询的Query Cache。
2. 什么样的数据适合存放到第二级缓存中?
1) 不多被修改的数据
2) 不是很重要的数据,容许出现偶尔并发的数据
3) 不会被并发访问的数据
4) 参考数据,指的是供应用参考的常量数据,它的实例数目有限,它的实例会被许多其余类的实例引用,实例极少或者历来不会被修改。
3. 不适合存放到第二级缓存的数据?
1) 常常被修改的数据
2) 财务数据,绝对不容许出现并发
3) 与其余应用共享的数据。
4. 经常使用的缓存插件 Hibernater二级缓存是一个插件,下面是几种经常使用的缓存插件:
◆EhCache:可做为进程范围的缓存,存放数据的物理介质能够是内存或硬盘,对Hibernate的查询缓存提供了支持。
◆OSCache:可做为进程范围的缓存,存放数据的物理介质能够是内存或硬盘,提供了丰富的缓存数据过时策略,对Hibernate的查询缓存提供了支持。
◆SwarmCache:可做为群集范围内的缓存,但不支持Hibernate的查询缓存。
◆JBossCache:可做为群集范围内的缓存,支持事务型并发访问策略,对Hibernate的查询缓存提供了支持。
5. 配置Hibernate二级缓存的主要步骤:
1) 选择须要使用二级缓存的持久化类,设置它的命名缓存的并发访问策略。这是最值得认真考虑的步骤。
2) 选择合适的缓存插件,而后编辑该插件的配置文件。
缓存是介于应用程序和物理数据源之间,其做用是为了下降应用程序对物理数据源访问的频次,从而提升了应用的运行性能。缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据。
缓存的介质通常是内存,因此读写速度很快。但若是缓存中存放的数据量很是大时,也会用硬盘做为缓存介质。缓存的实现不只仅要考虑存储的介质,还要考虑到管理缓存的并发访问和缓存数据的生命周期。
Hibernate的缓存包括Session的缓存和SessionFactory的缓存,其中SessionFactory的缓存又能够分为两类:内置缓存和外置缓存。Session的缓存是内置的,不能被卸载,也被称为Hibernate的第一级缓存。SessionFactory的内置缓存和Session的缓存在实现方式上比较类似,前者是SessionFactory对象的一些集合属性包含的数据,后者是指Session的一些集合属性包含的数据。SessionFactory的内置缓存中存放了映射元数据和预约义SQL语句,映射元数据是映射文件中数据的拷贝,而预约义SQL语句是在Hibernate初始化阶段根据映射元数据推导出来,SessionFactory的内置缓存是只读的,应用程序不能修改缓存中的映射元数据和预约义SQL语句,所以SessionFactory不须要进行内置缓存与映射文件的同步。SessionFactory的外置缓存是一个可配置的插件。在默认状况下,SessionFactory不会启用这个插件。外置缓存的数据是数据库数据的拷贝,外置缓存的介质能够是内存或者硬盘。SessionFactory的外置缓存也被称为Hibernate的第二级缓存。
Hibernate的这两级缓存都位于持久化层,存放的都是数据库数据的拷贝,那么它们之间的区别是什么呢?为了理解两者的区别,须要深刻理解持久化层的缓存的两个特性:缓存的范围和缓存的并发访问策略。
持久化层的缓存的范围
缓存的范围决定了缓存的生命周期以及能够被谁访问。缓存的范围分为三类。
1 事务范围:缓存只能被当前事务访问。缓存的生命周期依赖于事务的生命周期,当事务结束时,缓存也就结束生命周期。在此范围下,缓存的介质是内存。事务能够是数据库事务或者应用事务,每一个事务都有独自的缓存,缓存内的数据一般采用相互关联的的对象形式。
2 进程范围:缓存被进程内的全部事务共享。这些事务有多是并发访问缓存,所以必须对缓存采起必要的事务隔离机制。缓存的生命周期依赖于进程的生命周期,进程结束时,缓存也就结束了生命周期。进程范围的缓存可能会存放大量的数据,因此存放的介质能够是内存或硬盘。缓存内的数据既能够是相互关联的对象形式也能够是对象的松散数据形式。松散的对象数据形式有点相似于对象的序列化数据,可是对象分解为松散的算法比对象序列化的算法要求更快。
3 集群范围:在集群环境中,缓存被一个机器或者多个机器的进程共享。缓存中的数据被复制到集群环境中的每一个进程节点,进程间经过远程通讯来保证缓存中的数据的一致性,缓存中的数据一般采用对象的松散数据形式。
对大多数应用来讲,应该慎重地考虑是否须要使用集群范围的缓存,由于访问的速度不必定会比直接访问数据库数据的速度快多少。
持久化层能够提供多种范围的缓存。若是在事务范围的缓存中没有查到相应的数据,还能够到进程范围或集群范围的缓存内查询,若是仍是没有查到,那么只有到数据库中查询。事务范围的缓存是持久化层的第一级缓存,一般它是必需的;进程范围或集群范围的缓存是持久化层的第二级缓存,一般是可选的。
持久化层的缓存的并发访问策略
当多个并发的事务同时访问持久化层的缓存的相同数据时,会引发并发问题,必须采用必要的事务隔离措施。
在进程范围或集群范围的缓存,即第二级缓存,会出现并发问题。所以能够设定如下四种类型的并发访问策略,每一种策略对应一种事务隔离级别。
事务型:仅仅在受管理环境中适用。它提供了Repeatable Read事务隔离级别。对于常常被读但不多修改的数据,能够采用这种隔离类型,由于它能够防止脏读和不可重复读这类的并发问题。
读写型:提供了Read Committed事务隔离级别。仅仅在非集群的环境中适用。对于常常被读但不多修改的数据,能够采用这种隔离类型,由于它能够防止脏读这类的并发问题。
非严格读写型:不保证缓存与数据库中数据的一致性。若是存在两个事务同时访问缓存中相同数据的可能,必须为该数据配置一个很短的数据过时时间,从而尽可能避免脏读。对于极少被修改,而且容许偶尔脏读的数据,能够采用这种并发访问策略。 只读型:对于历来不会修改的数据,如参考数据,可使用这种并发访问策略。
事务型并发访问策略是事务隔离级别最高,只读型的隔离级别最低。事务隔离级别越高,并发性能就越低。
什么样的数据适合存放到第二级缓存中?
一、不多被修改的数据
二、不是很重要的数据,容许出现偶尔并发的数据
三、不会被并发访问的数据
四、参考数据
不适合存放到第二级缓存的数据?
一、常常被修改的数据
二、财务数据,绝对不容许出现并发
三、与其余应用共享的数据。
Hibernate的二级缓存
如前所述,Hibernate提供了两级缓存,第一级是Session的缓存。因为Session对象的生命周期一般对应一个数据库事务或者一个应用事务,所以它的缓存是事务范围的缓存。第一级缓存是必需的,不容许并且事实上也没法比卸除。在第一级缓存中,持久化类的每一个实例都具备惟一的OID。
第二级缓存是一个可插拔的的缓存插件,它是由SessionFactory负责管理。因为SessionFactory对象的生命周期和应用程序的整个过程对应,所以第二级缓存是进程范围或者集群范围的缓存。这个缓存中存放的对象的松散数据。第二级对象有可能出现并发问题,所以须要采用适当的并发访问策略,该策略为被缓存的数据提供了事务隔离级别。缓存适配器用于把具体的缓存实现软件与Hibernate集成。第二级缓存是可选的,能够在每一个类或每一个集合的粒度上配置第二级缓存。
Hibernate的二级缓存策略的通常过程以下:
1) 条件查询的时候,老是发出一条select * from table_name where …. (选择全部字段)这样的SQL语句查询数据库,一次得到全部的数据对象。
2) 把得到的全部数据对象根据ID放入到第二级缓存中。
3) 当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;查不到,若是配置了二级缓存,那么从二级缓存中查;查不到,再查询数据库,把结果按照ID放入到缓存。
4) 删除、更新、增长数据的时候,同时更新缓存。
Hibernate的二级缓存策略,是针对于ID查询的缓存策略,对于条件查询则毫无做用。为此,Hibernate提供了针对条件查询的Query缓存。
Hibernate的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都要从缓存中清空。