Hibernate缓存机制探讨

开发 后端
缓存是对或计算代价较大的原始数据的复制存储。通过Hibernate缓存机制,对缓存中的数据进行访问,可以缩短平均访问时间,提高数据的平均传输速度。

缓存是提高硬件和应用程序性能的一个关键因素,在对象映射框架中更是如此。因此,合理使用Hibernate缓存机制能够大幅度的提高Hibernate应用程序的性能。

Hibernate提供了两级缓存架构,第一级缓存是Session的缓存,第二级缓存是一个用户决定是否使用的缓存,能够借助与第三方的组件实现。Hibernate则提供了缓存管理接口,应用程序可以自由的对Hibernate缓存机制进行管理。

缓存是对或计算代价较大的原始数据的复制存储。通过在缓存(连续的内存空间)存储数据,对缓存中的数据进行访问,可以缩短平均访问时间,提高数据的平均传输速度。Hibernate缓存机制提供了这种高效传输的手段。

缓存首先出现在CPU中,由于CPU的速度很快,主存储器的存储速度无法与其相比,因而影响了计算机的执行效率。在CPU和主存储器之间加入了速度最快的SRAM作为CPU与相对低速的存储器之间交换数据的缓冲区,这样可以大幅度提高系统的执行效率,可且通过CACHE来事先读取CPU可能需要的数据。推广开来,凡是位于速度相差很大的两种硬件或应用之间的,用于协调两者数据传输差异的结构都可以称为缓存。
缓存将最近访问过的信息存储在特殊内存系统中以避免CPU在重新到主存储器中存取。在特定的硬件基础和应用架构之上,缓存往往是提升系统性能的关键因素之一。在使用数据库的应用系统中,缓存位于数据库和应用之间,在内存中保存底层数据库的数据副本(应用程序经常方位的数据),以便应用程序之间重内存中存取而不必频繁的方位数据库,因此提高了应用程序访问数据的效率。

缓存介于应用程序的数据访问层和数据库等数据源层之间,一般位于内存中,而数据库等数据源长来自硬盘或网络。相对于硬盘和网络,应用程序访问内存的速度显然要快的很多。不过如果缓存中数据量太大也可以放置到硬盘上,需要时在掉入内存,这样虽然速度慢些,但还是比直接从网络获取要快!

对于Hibernate而言,它是一个实现了对象关系映射的组件。应用程序中的数据通过Hibernate缓存机制中的持久化实例反映。这些持久化实例维护的数据是来自于底层数据库或即将同步更行到数据库的数据,为了获取这些数据,Hibernate必须频繁的访问数据库,产生大量的数据库连接操作和数据传输动作,效率较低。另外,Hibernate屏蔽了底层数据库的操作细节,让用户可以以操作对象的方式访问关系数据库中的数据,在对象关系映射转换的过程中,Hibernate势必付出了一些系统开销!

为了提升Hibernate的数据库访问效率并应对Hibernate封装底层数据库的内存开销,需要引入缓存策略。缓存作为数据库数据在内存中的临时容器,内涵了数据库数在内存中的临时副本。Hibernate读取所需数据时,首先在缓存中查找(先是一级缓存再次是二级缓存),若果缓存中存在需要的数据则称为命中(和CPU在一级缓存中取到需要的数据概念一样),然后就会直接返回数据,这样的话就避免了数据库调用的开销,不过如果缓存中没有所需要的数据还是会访问底层数据库。

Hibernate采用二级缓存体系,包括Session缓存(一级缓存)和SessionFactory缓存(二级缓存)。

(1)Session缓存是内置的,默认的,不能被卸载。Session维护了其自身生命周期中的一些持久化实例和它们的集合。(就像是一个方法中的变量)

(2)SessionFactory缓存即Hibernate二级缓存,按结构可以分为内置缓存和外置缓存两种。

针对缓存的生命周期的不同,我们可以将Hibernate的缓存分为三个层次:

1.事物级缓存

缓存只能被当前事物访问。这个事物可以是一个数据库事物(比如Session),也可以是某个应用程序大的事物。缓存的声明周期依赖于事物的生命周期,很显然,就像是一个方法中的变量(内部变量)方法执行完后,其内部变量就会小时除非我们在那个方法中将其存入一个全局变量的集合类中。因此,对于Session而言,事物级缓存有Session实现。Sessions内部维护一个数据缓存这个缓存随着Session的创建而建立,在Session关闭时将被JVM垃圾回收机制回收除非其还存在引用(即使把其放进一个全局变量中例如集合)。在Hibernate缓存机制中,Session内部缓存(说白了也就是Session内部变量)只能在Session实例范围中使用。

2.应用级缓存

缓存在某个应用范围被所有事务共享(指的是数据库事务Session)。缓存的声明周期依赖于应用程序的生命周期,当这个应用程序的生命周期结束时,缓存生命周球随之结束(我们不妨理解为全局变量)。不过这里就存在一个问题,由于缓存被所有事务共享,缓存可能被这些事务并发访问,这个主要必须依靠对缓存设置必要的事务隔离机制和缓存共享策略来尽力避免。另外,应用级缓存在整个应用范围内使用,数据量较大时可以存储在硬盘上。

对于Hibernate而言,应用级别缓存有SessionFactory实现。Session实例有SessionFactory创建,并共享SessionFactory的缓存。

其实我们可以这样理解Hibernate缓存机制中的SessionFactory与Session,以及一级缓存和二级缓存。SessionFactory是一个可执行类的话,二级缓存就相当于其内部的一个集合类作为其全局变量,而Session则可以看做其内部的一个方法(或者是内部方法中的内部类的实例),类的方法肯定是可以访问其类的变量(更何况全局变量),但是类的方法以结束其内部类就会立即消失而类的全局变量则依然存在知道这个类执行完所有方法。因此,如果我们想保存数据库数据副本到二级缓存中,只能在这个类运行内部方法时把带到的数据存到全局变量(比如集合类中)中。

 

【编辑推荐】

  1. Hibernate 删除出现异常的解决方案
  2. Hibernate一对多关系的处理
  3. Struts与Hibernate的完美结合方案
  4. Hibernate单元测试的方法HSQLDB详述
  5. 解析Hibernate的批量删除功能
责任编辑:佚名 来源: JavaEye
相关推荐

2009-08-13 16:57:37

.NET缓存机制

2009-06-18 14:51:12

Hibernate缓存Hibernate

2010-03-01 17:57:11

WCF缓存机制

2009-06-29 08:48:41

Hibernate缓存

2012-02-03 11:31:33

HibernateJava

2009-09-25 13:51:13

Hibernate S

2009-09-25 10:25:54

Hibernate缓存

2009-09-23 17:03:08

Hibernate S

2010-07-21 09:38:15

PHP缓存技术

2009-09-22 11:24:07

Hibernate查询

2009-09-22 10:50:04

Hibernate c

2010-11-22 14:18:32

MySQL锁机制

2009-06-30 14:08:00

Hibernate缓存

2009-09-22 09:31:15

Hibernate主键

2009-09-23 16:30:01

Hibernate f

2012-06-02 00:55:44

HibernateflushJava

2009-05-11 13:48:00

ASP.NET 2.0缓存效率

2009-06-17 15:13:30

2009-09-27 14:53:38

Hibernate S

2011-07-04 16:48:56

JAVA垃圾回收机制GC
点赞
收藏

51CTO技术栈公众号