2012-01-01 156 views
0

我想使用休眠批量更新,我试过批量插入并能正常工作,这里的配置我使用休眠:Hibernate的批量更新不起作用

<property name="hibernateProperties"> 
      <value> 
       hibernate.dialect=org.hibernate.dialect.MySQLDialect 
       hibernate.hbm2ddl.auto=update 
       hibernate.show_sql=false 
       hibernate.jdbc.fetch_size=100 
       hibernate.jdbc.batch_size=100 
       hibernate.jdbc.batch_versioned_data=true 
       hibernate.order_inserts=true 
       hibernate.order_updates=true 
       hibernate.cache.use_query_cache=false 
       hibernate.cache.use_second_level_cache=false 

      </value> 
     </property> 

和这里的DAO代码:

public void updateBulkEmployees(List<Employee> employees) throws Exception { 

     for (int i = 0; i < employees.size(); i++) { 
      sessionFactory.getCurrentSession().update(employees.get(i)); 
      if (i % 100 == 0) { 
       sessionFactory.getCurrentSession().flush(); 
       sessionFactory.getCurrentSession().clear(); 
       log.debug("Flushing batch:" + (int) (i/100)); 
      }    

     } 

      sessionFactory.getCurrentSession().flush(); 
      sessionFactory.getCurrentSession().clear(); 

    } 

ISSUE:我可以注意到,方法执行需要很多时间(完全相同的时间,而不使用批处理),所以批量更新不起作用,我错过配置中的某些东西或做错了什么? 请指教,谢谢。

+0

仅仅因为它需要相同的时间并不意味着更新没有批处理。这也可能意味着使用配料,但根本不会让事情变得更快。 – 2012-01-01 12:21:05

+0

所以你的意思是说上面的配置没有什么错,或者不能改进或者调整得更多? – 2012-01-01 12:29:51

+0

@JB Nizet,以及如何在这种情况下加快速度,你有什么建议? – 2012-01-01 12:31:06

回答

0

不应该第二个“sessionFactory.getCurrentSession()。flush();”在循环之外?

+0

在for循环之外尝试过,并且获得相同的性能。 – 2012-01-01 12:04:10

1

你怎么知道批量插入的作品?观察mysql.log是了解批量插入/更新是否有效的唯一方法(即使使用批处理,Hibernate也始终记录单个查询)。

要在MySQL中使用批处理,必须在URL中设置特定的JDBC参数(Hibernate批处理使用JDBC批处理功能)。试着用:

http://your_host:your_port/database?rewriteBatchedStatements=true

,不要使用GenerationType.AUTO或GenerationType.IDENTITY作为ID生成。在这种情况下,Hibernate会禁用静默批处理功能。

提示:只需要中间刷新以避免OutOfMemory。 Hibernate尝试尽可能最后查询数据库,因此如果尝试更新1000000个实体,它将保留所有实体直到提交。