2012-08-30 44 views
0

我正在爲我的Play Framework 1.2.4項目中的批處理作業使用無狀態會話。Hibernate無狀態會話處理錯誤的最佳方式是什麼?

我插入和更新行相當不錯,但我不知道當發生異常時該怎麼辦。繼承人我的代碼:

try{ 
     statelesssession.insert(someobject); 
    } 
catch(ConstraintViolationException e) //It happens from time to time dont ask me why.. 
    { 
     ??????transaction.rollback();????? THATS MY CONCERN 
    } 
finally{ 
     transaction.commit(); 
    } 

我需要知道的是,我每隔100個插入提交數據。我想知道,如果約束條件發生在第56條記錄中,並且交易進行了回滾,我是否會失去其他55條記錄?

如果是的話,我在約束性違規行爲中必須做些什麼?或者我應該在每一條記錄中做出迴避?

+1

我認爲您應該向您的客戶提出這個問題,而不是在這裏..但是如果您在沒有提交**的情況下回滾到第56條記錄,您將失去**以前的更改,直到最後一次提交。 – mericano1

+0

坦克,我不確定它是否只是回滾相應的數據或所有批次。 – dreampowder

+0

我還有另外一個問題,當我得到異常時,我認爲該內存仍然存在於內存中,因爲我的內存使用量越來越高,直到內存不足。發生異常時如何從內存中擦除數據? – dreampowder

回答

0

如果您提交每100個插入,則在第56個插入之後的回滾還將撤銷之前的所有55個插入。

您可以在每次插入後進行提交,但可以批量插入確實很多很慢而且不推薦的行。

該解決方案使用保存點。

設置保存點相對較快。每次插入後都可以完成。設置保存點不會將任何數據寫入數據庫 - 您仍然需要稍後提交 - 但只有在最後一個保存點之前纔會執行回滾。

因此,在您的示例中,您每提交一次(或任何)100行(並確保在最後一行之後),並在每行之後設置一個保存點。當出現錯誤並且回滾操作時,只有錯誤的插入操作被撤消,其他操作不會被觸摸。

有關說明,請參閱java.sql.Connection.setSavepoint,java.sql.Savepoint或here

+0

聽起來像是個好主意!謝謝! – dreampowder

1

如果您回滾,您也將失去事務中的所有以前的記錄。如果您只想丟失具有約束例外的記錄,那麼您可以將每個批次的記錄保存在一個列表中,並在批量炸彈繼續批量處理時切換到逐個提交。

1

在這種類型的用例中,您還有另一項工作可以將所有數據分割爲100個對象,併爲這些對象啓動子作業。

在這種情況下對我來說最好的辦法是拋出異常。然後主作業得到這個異常,所有你的100個對象都回滾。然後,主工作可以進入這些對象的另一種模式,並重新啓動每個對象的子作業。那麼只有拋出異常的那個不會被保存。

這是批處理的典型處理。如果一切正常,你的批處理速度很快,因爲你提交了每100個對象,但是如果出現錯誤,你會回退到單個對象提交中,因此你不會保存失敗的對象。

但正如mericano1所說,你的案件的正確行爲是一個商業規則的問題。

+0

所以這裏還有另一個問題。當發生異常時,java.exe的內存使用量正在增加(我猜java正在將內存保存在內存中)。發生異常時回收該數據的最佳方式是什麼? – dreampowder

+1

只要你沒有一個對象的參考,gc會自動做到這一點。要檢查Java內存使用情況,請不要使用系統工具跟蹤它,但使用像visualvm這樣的特定工具來跟蹤堆使用的演變 –

相關問題