2008-04-20

Hibernate 批量处理 insert

关键字: java ee
批量插入

  在项目的开发过程之中,由于项目需求,我们常常需要把大批量的数据插入到数据库。数量级有万级、十万级、百万级、甚至千万级别的。如此数量级别的数据用Hibernate做插入操作,就可能会发生异常,常见的异常是OutOfMemoryError(内存溢出异常)。
  基本思路:优化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>

配置hibernate.jdbc.batch_size参数的原因就是尽量少读数据库,hibernate.jdbc.batch_size参数值越大,读数据库的次数越少,速度越快。从上面的配置可以看出,Hibernate是等到程序积累到了50个SQL之后再批量提交。

    hibernate.jdbc.batch_size参数值也可能不是设置得越大越好,从性能角度上讲还有待商榷。这要考虑实际情况,酌情设置,一般情形设置30、50就可以满足需求了。
    插入10000条数据为例,如下:

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

在一定的数据规模下,这种做法可以把系统内存资源维持在一个相对稳定的范围。

如果启用了二级缓存,从机制上讲Hibernate为了维护二级缓存,我们在做插入、更新、删除操作时,Hibernate都会往二级缓存充入相应的数据。性能上就会有很大损失,建议在批处理情况下禁用二级缓存。
评论
Allen 2008-04-24   回复
Hibernate不是用来干这个的……
marky 2008-04-24   回复
有个疑问,如果访问量大的话,到50个SQL在批量处理客户会认为系统有问题,反应这么慢

另:
引用
建议在批处理情况下禁用二级缓存


请问如何禁用2级缓存?可否动态设置
movingboy 2008-04-24   回复
Joo 写道
上万Hibernate都应付不来?

你是在质疑我的问题吗?我并不是说Hibernate对付不了上万条记录,只是想了解一下实际应用中到底有什么情况需要“使用Hibernate来应付上万条记录”?是不是无法使用数据库工具或SQL脚本来处理?前者比后者有哪些优势?
Joo 2008-04-23   回复
上万Hibernate都应付不来?
movingboy 2008-04-23   回复
记录上万的操作还用Hibernate来弄啊?这比直接用数据库提供的工具或者SQL脚本来做好在哪里?
hantsy 2008-04-23   回复
batch size , fetch size 并不是设置下就能够提高性能,还要看数据库的支持。
发表评论

提醒: 该博客已发表在公共论坛,博客所有留言会成为论坛回贴,留言请注意遵守论坛发贴规则

您还没有登录,请登录后发表评论

chen-516888
搜索本博客
博客分类
我的相册
1a8a55a2-8a9d-35ea-bba5-9d7fc566e002-thumb
IMG_9122
共 1 张
最近加入圈子
存档
最新评论