hibernate缓存管理与性能调优

缓存管理

1.缓存概述
  缓存(cache)在java应用程序中是一组内存中的集合实例。它保存着永久性存储源(如硬盘上的文件或者数据库)中数据的备份,它的读写速度比读写硬盘的速度快。应用程序在运行时直接读写缓存中的数据,只在某些特定时刻安装缓存中的数据来同伴更新数据存储源。如果缓存中存放的数据量非常大,也会用硬盘作为缓存的物理介质。
   缓存的作用就是降低应用程序直接读写永久性数据存储源的频率,从而增强应用的运行性能。
缓存的实现不仅需要作为物理介质的硬件(内存),同时还需要用于管理缓存并发访问和过期等策略的软件。
2 缓存范围分类
缓存的范围决定了缓存的生命周期及其可以被谁访问。缓存的范围分为以下三类:
1)事务范围:缓存只能被当前事务访问。缓存的生命周期依赖于事务的生命周期,当事务结束时,缓存也就结束生命周期。在此范围下,缓存的介质是内存。
2)进程范围:缓存被进程内的所有事务共享。这些事务有可能是并发访问缓存,因此必须对缓存采取必要的事务隔离机制。
3)集群范围:在集群环境中,缓存被一个机器或者多个机器的进程共享。缓存的数据被复制到集群环境中的每个进程节点,进程间通过远程通信来保证缓存中的数据一致性。对于大多数应用来说,应该慎用集群范围的缓存,因为访问的速度并不一定比直接访问数据库数据的速度快很多。
3. 缓存的并发访问策略
在进程范围或集群范围的缓存,会出现并发问题。因此可以设置4中类型的并发访问策略,每一种策略对应一种事务隔离级别。事务的隔离级别越高,并发性能就越低。
1)事务型(Transactional)策略
2)读写型(Read-Write)策略
3)非严格读写型(Nonstrict-read-write)策略
4)只读型(Read-only)策略

4.Hibernate中的缓存
Hibernate中提供两级缓存,第一级别的缓存是Session级别的缓存,它是属于事务范围的缓存。
第二级别的缓存是SessionFactory级别的缓存,它是属于进程范围范围的缓存,这一级别的缓存可以进行配置和更改,并且可以动态加载和卸载。
Hibernate还为查询结果提供一个查询缓存,它依赖于二级缓存。


 

5.一级缓存的管理
Session级别的缓存由hibernate自动管理。当应用程序调用Session的CRUD方法及调用查询接口的list(),iterate()等方法时,如果在Session缓存中还不存在相应的对象,Hibernate就会把改对象加入到Session缓存中。如果在Session缓存中已经存在这个对象,就不需要再去数据库加载而是直接使用缓存中的这个对象,可以减少访问数据库的频率,提高程序的运行效率。当Hibernate清理缓存时(默认是提交事务的时候),Hibernate会根据缓存中对象的状态来同步数据库中的数据状态,在关闭Session时,会清空Session缓存中的所有对象。

 

一级缓存不能控制缓存的数量,所以要注意大批量操作数据时可能造成内存溢出;可以用
evict(Object obj):从缓存中清除指定的持久化对象。

clear():清空缓存中所有持久化对象。

 flush(): 进行清理缓存(此时缓存中的数据并不丢失)的操作,让缓存和数据库同步 执行一些列sql语句,但不提交事务。

 commit():先调用flush() 方法,然后提交事务. 则意味着提交事务意味着对数据库操作永久保存下来。

 

可以写一个for循环,Session可以批量插入上万条数据。如下面的代码:
             For(int i=0;i<10000;i++){
  Session.save(object);
}
这样写的代码会产生一个什么问题?会使一万个对象的缓存全部存在于内存中,这样做加大了内存的压力。所以应该定期清理session的缓存。
当做批量插入或批量更新时,必须通过经常调用Session的flush()以及稍后调用clear()来控制一级缓存的大小,这样内存才能保证足够的空间。

 

for(int i=1;i<=50;i++){
Department dept = new Department();
dept.setName("软件"+i);
session.save(dept);
for(int j=1;j<=100;j++){
Employee emp = new Employee();
emp.setName("张三"+j);
emp.setSalary(j);
    emp.setDept(dept
    session.save(emp);
    if(j%50==0){
    session.flush();
    session.clear();
    }
}
}
6.二级缓存的管理
二级缓存是SessionFactory级别的缓存,它的使用过程如下:
1)执行条件查询的时候,发出“select * from table_name where …”这样的SQL语句查询数据库,一次获得所有的数据对象。
2)把获得的所有数据对象根据ID放入到二级缓存中。
3)当Hibernate根据ID访问数据对象时,首先从Session缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;还没查到,再查询数据库,把结果按照ID放入到二级缓存。
4)删除、更新和增加数据的时候,同时会更新到二级缓存中。
Hibernate的二级缓存策略是针对ID查询的缓存策略,对于调节查询则毫无作用。为此,hibernate提高了单独针对条件查询的查询缓存。

适合存放到二级缓存中的数据有:
1)很少被修改的数据。
2)不是很重要的数据,允许出现偶尔的并发的数据。
3)很多系统模块都要用到
4)不是私有的数据,是共享的

什么样的数据不适合放在二级缓存中???
财务数据  安全性的数据 也就是不想让别人看到的数据和特别重要的数据

猜你喜欢

转载自zhangxing119.iteye.com/blog/1774944