2014-09-29 182 views
1

我有一個持久的hibernate管理@entity Obj在休眠,其中有字段id,fieldA和fieldB,等等。有沒有辦法避免HibernateOptimisticLockingFailureException?

在某些類中,我有兩個@Transactional方法updateA()和updateB()。
updateA()通過它的id獲得一個Obj,做一些處理,並更新它的fieldA。
updateB對fieldB做相同的操作。

我也有兩個客戶不斷提出請求。 一個客戶端總是發出調用updateA()的請求,而另一個客戶端總是調用updateB()。
他們都通過一個現有的Obj相同的ID。

有沒有辦法避免HibernateOptimisticLockingFailureException一直髮生,或一旦成功處理它,因爲每個方法更新不同的字段?某種合併?

只是爲了完成圖片,調用updateA()的線程實際上調用了與updateA()類似的其他事務方法,但沒有更新fieldB。

起初,我只是試圖捕捉異常,並重新嘗試第二次操作。但有時它也會第二次失敗......這似乎不是一個好的解決方案。

+0

您正在使用的版本('@ Version')您實體? – 2014-09-29 04:36:47

+0

不使用@Version。如果兩個客戶端同時更新fieldB,將讀取它 – inor 2014-10-01 04:57:04

回答

1

如果你可以安全地做到這一點,最簡單的方法是從樂觀鎖定排除fieldB

import org.hibernate.annotations.OptimisticLock; 

/* ... */ 

@OptimisticLock(excluded=true) 
private B fieldB; 
+0

不會失敗嗎? – 2014-09-29 04:46:04

+0

@ThomasStets以什麼方式失敗? – 2014-09-29 04:47:13

+0

好吧,我錯過了他只有一個客戶更新fieldB的事實。但是,如果有更多的客戶端可以在沒有Hibernate注意的情況下覆蓋另一個客戶端的更新。 – 2014-09-29 04:52:01

1

您可以使用automatic optimistic locking retry mechanism

對於您需要添加以下依賴:

<dependency> 
    <groupId>com.vladmihalcea</groupId> 
    <artifactId>db-util</artifactId> 
    <version>0.0.1</version> 
</dependency> 

然後,只需標記與以下標註你的服務的方法:在

@Retry(times = 5, on = OptimisticLockException.class) 
相關問題