2016-05-16 61 views
0

我正面臨一個問題,即通過使用get(Serializable,Class,LockOptions)方法和LockOptions.UPGRADE獲取該行的鎖。休眠:它是否在get()和LockOptions.UPGRADE後重新加載對象

正在獲取鎖定的對象已存在於會話中。 一旦執行select ... for update,我發現如果在對象的初始提取後和在get(Serializable,Class,LockOptions)之前,表中對應的行已被更改,則該方法不返回更新的對象。

我想澄清以下內容, 這是因爲我試圖獲取對象已在會話緩存中加載的行的鎖定。

Hibernate只是在後臺觸發select ... for update,但不會重新加載對象,而是如果找到會從會話緩存中獲取一個?

以下是我如何獲取鎖定的代碼片段。

List<MyObject> listOfMyObject = dao.getListOfMyObjects(); 

for(MyObject m : listOfMyObject){ 
    m = session.get(id,MyObject.class,LockOptions.UPGRADE); 
    // 
} 

鎖定機制工作正常。讓我們說讓ThreadOne事務處理鎖,我可以看到另一個ThreadTwo事務正在等待獲取鎖。現在,當ThreadOne事務釋放鎖時,第二個事務通過session.get(id,MyObject.class,LockOptions.UPGRADE)方法獲取它,返回的對象沒有ThreadOne完成的更新值。

回答

0

理想情況下,當你使用LockOptions.Upgrade時,它是一種悲觀的鎖定。

它不應該理想地允許任何其他事務來更改記錄,因爲它是該數據庫行上的一種悲觀鎖。

理想情況下,不要使用悲觀鎖定,而應使用某種版本/時間戳列進行樂觀鎖定,在該列中您可以通過編程方式實現更多控制。

0

是的,根據Hibernate docs,session.get(Serializable,Class,LockOptions)從會話中加載實例(如果它已經存在)。對於您的情況,您可能希望在session.get(Serializable,Class,LockOptions)之後立即使用session.refresh(Object object)以從數據庫中重新讀取實例的狀態。