`
huzhiyong56
  • 浏览: 26867 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Hibernate遇到处理大数据的问题

 
阅读更多

       今天同事搞个东西,插入8000条数据,到了3000条就卡死了。。应该是session没释放,以下整理出出现该问题的解决方案。

      大批量的数据插入到数据库。数量级有万级、十万级、百万级、甚至千万级别的。如此数量级别的数据用Hibernate做插入操作,就可能会发生异常,常见的异常是OutOfMemoryError(内存溢出异常)。

     Hibernate插入操作的机制:Hibernate要对它内部缓存进行维护,当我们执行插入操作时,就会把要操作的对象全部放到自身的内部缓存来进行管理。
     Hibernate
的缓存:Hibernate有内部缓存与二级缓存之说。由于Hibernate对这两种缓存有着不同的管理机制,对于二级缓存,我们可以对它的大小进行相关配置,而对于内部缓存,Hibernate就采取了放任自流的态度了,对它的容量并没有限制。现在症结找到了,我们做海量数据插入的时候,生成这么多的对象就会被纳入内部缓存(内部缓存是在内存中做缓存的),这样你的系统内存就会一点一点的被蚕食,如果最后系统被挤了,也就在情理之中了

    处理这个问题的两种方案:

     1 优化Hibernate,程序上采用分段插入及时清除缓存的方法。

     2 绕过Hibernate API ,直接通过 JDBC API 来做批量插入,这个方法性能上是最 好的,也是最快的。
   
对于上述中的方法1,其基本是思路为:优化Hibernate,在配置文件中设置hibernate.jdbc.batch_size参数,来指定每次提交SQL的数量;程序上采用分段插入及时清除缓存的方法(Session实现了异步write-behind,它允许Hibernate显式地写操作的批处理),也就是每插入一定量的数据后及时的把它们从内部缓存中清除掉,释放占用的内存。 

    设置hibernate.jdbc.batch_size参数,可参考如下配置。 
    

<hibernate-configuration> 
<session-factory> 
......... 
<property name=” hibernate.jdbc.batch_size”>50</property> 
......... 
<session-factory> 
<hibernate-configuration> 

 

 

 

 

Session session=HibernateUtil.currentSession(); 
Transatcion tx=session.beginTransaction(); 
for(int i=0;i<10000;i++) 
...{ 
Student st=new Student(); 
st.setName(“feifei”); 
session.save(st); 
if(i%50==0) //以每50个数据作为一个处理单元 
...{ 
session.flush(); //保持与数据库数据的同步 
session.clear(); //清除内部缓存的全部数据,及时释放出占用的内存 
} 
} 
tx.commit(); 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics