2012-01-01 63 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個實體,它將保留所有實體直到提交。