2014-01-21 91 views
2

我正在使用Hibernate和Spring,並且我想編寫服務代碼以滿足在兩個單獨的線程中使用DAO來獲取實體實例通過id,並且它在每種情況下都是相同的id /數據庫行,並且我不希望給定的方法在該實體實例的兩個線程中同時運行。如何編寫在實體實例上同步的Java代碼

我不知道是否有可能寫...

synchronized(entity) {} 

或者這是否是不可能的,因爲從DAO檢索時,每個線程可以創建在內存中的對象的不同實例,都指的是同一個實體實例。

如果Hibernate確實可以在內存中爲同一個實體實例創建多個對象,那麼執行我想要做的事情的最佳方法是什麼?

+0

private static Object sharedLock = new Object();你可以使用共享鎖嗎? –

回答

2

這是行不通的。當您從數據庫加載數據時,Hibernate可能(並且經常會)返回不同的實例。

原因是兩個線程可能想要同時訪問同一個對象。如果Hibernate會給出同一個實例,那麼通過一個線程的更改可能(或不)對第二個線程可見。

爲了達到您想要的效果,您需要一箇中央註冊表,您可以通過ID獲取實體的鎖定。這樣,每個線程都可以這樣做:

Object lock = lockFactory.getLock(id); 
synchronized(lock) {...} 

然後,工廠可以確保所有線程都獲得相同ID的同一個鎖。

+0

謝謝Aaron,這正是我需要的解決方案。不允許投票給你,因爲我沒有任何聲望:) –

+0

偉大的學習對我來說也是:) –

+1

@Aaron我明白你建議的註冊表將保持對鎖對象的引用。隨着時間的推移,這些尺寸可以達到很大的尺寸,您是否對這些物體如何清潔有任何想法。謝謝 –