2017-08-14 97 views
3

有人可以解釋我Hibernate批量插入如何工作?

hibernate.jdbc.batch_size=1000 

if (i % 100 == 0 && i>0) { 
        session.flush(); 
        session.clear(); 
       } 

如何一起工作的? ...

+0

https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/batch.html – soorapadman

+0

@soorapadman,謝謝爲文章..但是,如果hibernate.jdbc.batch_size是不同於我的沖洗循環? –

回答

1

hibernate.jdbc.batch_size確定最大批處理大小執行。如果在達到指定的批處理大小之前執行隱式或顯式刷新(the same table的待處理插入或更新語句的數目),則所有待處理語句都打包在一個批處理中,並重新啓動「累積」語句。

因此,在您的示例中,您將執行由100條語句組成的批處理。或者,例如,如果批量大小爲100,模數除法器爲500,那麼當執行刷新操作時,您將執行5個批次,每個批次包含100個語句。

+0

你可以看看https://stackoverflow.com/questions/46214322/how-to-force-hibernate-to-remove-orphans-before-update? – gstackoverflow

0

批處理允許您將相關的SQL語句分組到一個批處理中,並使用一次調用將它們提交給數據庫。

我們爲什麼需要

重要的是要記住,每次更新添加到Statement或PreparedStatement是由數據庫單獨執行。這意味着,其中一些可能會失敗之前成功。所有成功的語句現在都應用於數據庫,但其他更新可能不會。這可能會導致數據庫中的數據不一致。

爲了避免這種情況,您可以在事務中執行批量更新。在事務內部執行時,您可以確保執行所有更新,或者不執行任何更新。任何成功的更新都可以回滾,以防其中一個更新失敗。

什麼是批處理和法拉盛

批量大小和沖洗是不同的東西。當您將hibernate.jdbc.batch_size設置爲1000這意味着休眠將執行批量插入或更新至1000實體。 flush操作可用於在事務提交之前將所有更改寫入數據庫

如果您的批處理大小設置爲1000,並且您沖洗每100個實體,Hibernate將執行大量小批量的100個插入或更新語句10次​​。

請閱讀這個鏈接如下:

http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/batch.html

Why number of objects being flushed should be equal to hibernate.jdbc.batch_size?

3

休眠特性hibernate.jdbc.batch_size是休眠的方式來優化你的插入或更新statetment而沖洗循環大約是內存耗盡。

沒有BATCHSIZE當您嘗試保存一個實體休眠火1 INSERT語句,因此,如果你有一個大的收集工作,對每個保存休眠火1個語句

想象一下下面的代碼塊:

for(Entity e : entities){ 
session.save(e); 
} 

這裏hibernate會觸發你的集合中的每個實體1插入語句。如果你的集合中有100個元素,那麼100個插入語句將被觸發。 這種方法並不適合2個主要原因非常有效:

  • 1)您成倍增加1級高速緩存,並且可能會與OutOfMemoryException很快完成。
  • 2)由於每條語句的網絡往返導致性能下降。

hibernate.jdbc.batch_size和flush flush有2個不同的用途,但是互補。

Hibernate使用第一個來控制批量中有多少個實體。休眠下使用java.sql.Statement.addBatch(...)executeBatch()方法。

因此hibernate.jdbc.batch_size會告訴休眠在調用executeBatch()之前,必須調用addBatch()多少次。

所以設置這個屬性並不能阻止你的內存耗盡。

爲了照顧內存,您必須定期刷新會話,這就是沖洗循環的目的。

當你寫:

for(Entity e : entities){ 
if (i % 100 == 0 && i>0) { 
        session.flush(); 
        session.clear(); 
       } 
} 

你告訴Hibernate來沖洗,清除每100個實體(你釋放內存)會議。

那麼現在2之間的聯繫是什麼?

爲了達到最佳效果,您必須定義jdbc.batch_size和您的沖洗參數相同。

如果你定義一個沖洗PARAM下,你選擇這樣hibernate會更頻繁地刷新會話,這樣它會創建小批量的batch_size時,直到它到達btach大小 當2是效率不高

同樣的休眠只會執行批量的最佳尺寸,除了最後一個,如果集合的大小不是你的batch_size的倍數。

你可以看到更多細節如下post關於最後一點