2015-05-29 36 views
3

環境休眠節省了陳舊的數據與hibernate.jdbc.batch_versioned_data

的Hibernate 4.2

ojdbc6 - 甲骨文11.2.0.3.0 JDBC 4.0

Oracle數據庫11g

問題

我們跟着許多建議ations來配置我們的Hibernate批處理方式如下:

<property name="hibernate.jdbc.batch_size">100</property> 
<property name="hibernate.order_inserts">true</property> 
<property name="hibernate.order_updates">true</property> 
<property name="hibernate.jdbc.batch_versioned_data">true</property> 

我們檢查日誌,我們看到生成的SQL語句進行批處理。但是,如果兩個事務同時修改相同的版本化實體行,Hibernate將成功提交它們兩個,導致丟失最後提交的事務中的衝突更新(兩個事務中保存非衝突數據,因此最後一個事務離開數據庫處於不一致的狀態)。

令人驚訝的是,這種行爲很少有文檔。 Hibernate的官方documentation說:這個屬性

hibernate.jdbc.batch_versioned_data

設置爲true,如果從你則ExecuteBatch JDBC驅動程序返回正確的行數()。通常可以安全地打開此選項,即 。然後休眠將使用批量的 DML自動版本化數據。默認爲false。

平時安全?在注意到整個版本被破壞之前,我們幾乎將它發送到了生產環境。

我們一個blog發佈五年前Google搜索出描述這個古怪;顯然Hibernate在很長一段時間內對此沒有做任何事情。

是否有任何理由爲什麼Hibernate的行爲也是這樣嗎?它從jdbc驅動程序獲取更新行數未知的信息,爲什麼它不會拋出異常來表示它,而是留下了版本檢查已成功通過的印象?

+0

有你累了使這個'<屬性名= 「hibernate.order_updates」>真'假? – Babel

回答

4

oracle驅動程序應該返回正確的行數。如果情況並非如此,我會感到驚訝。你能否確認司機的結果是正確的? 你可以打開Hibernate日誌記錄來檢查它。

幾件事情要檢查:

  1. 記錄實際的SQL被髮送到數據庫,並檢查該版本列在where子句中提到。不確定SQL是否通過Hibernate記錄批處理記錄,那麼您可能不得不採取不同的方式記錄SQL然後(例如,p6spy)

  2. 如果行計數在併發更新過程中被正確返回,那麼應用程序工作正常。通過檢查版本列的值是否更新得到更正來確認。

更新 根據下面的鏈接,這個問題一直是目前與Oracle驅動程序,直到11g和固定版本12C

https://hibernate.atlassian.net/browse/HHH-3360

對於之前的Oracle版本有一些額外的應提供有用的信息,即提供定製解決方案。

其他資源: https://hibernate.atlassian.net/browse/HHH-5070

+0

oracle驅動程序返回-2(未知);我調試它:'org.hibernate.jdbc.Expectations.BasicExpectation.checkBatched'。 –

+0

這是由Hibernate以批處理更新unknown_在調試級別(另一個令人驚訝的事情,這應該至少警告,但在我看來,最直觀的行爲將拋出異常在這裏)記錄_Success。 1)實際SQL包含where子句中的版本列。 2)在兩個事務結束後(第一個事務寫入的值),Version列增加1。 –

+0

請檢查我的更新回答 – codedabbler