2010-06-12 66 views
9

我使用Criteria API檢索hibernate中的對象列表。不過,我需要鎖定這些對象,因爲另一個同時執行的線程將獲得確切的對象,並且只有其中一個線程會在沒有悲觀鎖定的情況下成功。如何使用Criteria API指定悲觀鎖定?

我試過像下面,但它不工作。

List esns = session 
    .createCriteria(Reddy_Pool.class) 
    .add(Restrictions.eq("status", "AVAILABLE")) 
    .add(Restrictions.eq("name", "REDDY2")) 
    .addOrder(Order.asc("id")) 
    .setMaxResults(n) 
    .setLockMode(LockMode.PESSIMISTIC_WRITE) //not working at all 
    .list(); 

更新:我這個發言後進行更新,所以,我想這兩個線程讀取不同的行或至少第二線程必須等待,直到第一個線程與該交易完成,離開鎖。

而hibernate生成的查詢如下。

Hibernate: select this_.id as id1_0_, this_.name as name1_0_, 
this_.orderitem_id as orderitem3_1_0_, this_.status as status1_0_, 
this_.store as store1_0_, this_.vendor as vendor1_0_, this_.version as version1_0_ 
from reddy_pool this_ 
where this_.status=? and and this_.name=? order by this_.id asc limit ? 

更新:似乎在3.5.2版本帕斯卡爾Thivent(非常感謝帕斯卡)中提到的錯誤,我已經加入爲成員和看問題。希望它會包含在下一個版本中。

但是我試着用session.buildLockRequest()的另一種方法嘗試......但是我無法弄清楚如何使用它,並且使用下面的代碼根本沒有任何效果。

for (int i=0; i < n; i++) 
    session.buildLockRequest(LockOptions.UPGRADE).lock(esns.get(i)); 
+0

「不工作」是什麼意思?沒有鎖的AFAIK兩次讀取都應該成功。 – 2010-06-12 11:50:40

+0

@Péter,更新了我的問題。基本上我想在這個選擇後執行更新。 – Reddy 2010-06-12 11:57:20

回答

3

您使用的是什麼版本的Hibernate?這可能是HHH-5275?你確定沒有生成FOR UPDATE聲明嗎?你能顯示生成的SQL嗎?

+0

這是由休眠生成的查詢(版本:3.5.2 Final) 是的,這看起來像HHH-5275,所以這意味着我們必須等到下一個版本? :( 休眠:選擇this_.id作爲id1_0_,this_.name作爲name1_0_,this_.orderitem_id作爲orderitem3_1_0_,this_.status作爲status1_0_,this_.store作爲store1_0_,this_.vendor作爲vendor1_0_,this_.version作爲version1_0_從reddy_pool this_其中this_.status =?和this_.name =?order by this_.id asc limit? – Reddy 2010-06-12 12:30:20

+0

Thanks Pascal。我試過另一種方法來使用會話來放置鎖(請參閱我的問題中的第二次更新),但它不起作用 – Reddy 2010-06-12 12:44:22

+0

因爲這個問題,我不得不換掉我的標準查詢,這似乎是一個大問題 - 爲什麼HH-5275被記錄爲次要? – 2010-10-14 17:50:01