2013-10-09 61 views
4

我想在JPA中使用悲觀鎖定,在Hibernate 3上對Postgres數據庫。我無法讓鎖定超時 - 它似乎永遠掛起。JPA悲觀鎖定嘗試永不超時

下面是一個例子:

EntityManagerFactory factory; 

// (initialise the factory) 

EntityManager em1 = factory.createEntityManager(); 
EntityManager em2 = factory.createEntityManager(); 

// em1 gets a lock 

EntityTransaction transaction1 = em1.getTransaction(); 
transaction1.begin(); 
MyObject object1 = em1.find(MyObject.class, 1, LockModeType.PESSIMISTIC_READ); 

// em2 tries for a lock 

Map<String,Object> timeoutProperties = new HashMap<String,Object>(); 
timeoutProperties.put("javax.persistence.lock.timeout", 5000); 

EntityTransaction transaction2 = em2.getTransaction(); 
transaction2.begin(); 
MyObject object2 = em2.find(MyObject.class, 1, LockModeType.PESSIMISTIC_READ, timeoutProperties); 

// After five seconds I expect em2 to bail out, but it never does. 

transaction1.rollback(); 
transaction2.rollback(); 

據我瞭解,EM2應該已經嘗試了最多五秒鐘(5000毫秒)來獲得鎖,然後應該拋出的異常。代碼會變得僵局。

如果我在兩個不同的線程中運行該函數,那麼當thread1(em1)釋放它時,我發現thread2(帶有em2)會獲得鎖。所以鎖定正在發生,只是從不超時。

我得到相同的效果與PESSIMISTIC_WRITE,並與任何超時值(2ms的,0毫秒「不等待」)等

我使用Hibernate的3.6.10決賽(最新的Hibernate 3版)和Postgres jdbc驅動程序9.2-1003.jdbc4(最新的驅動程序)。我正在運行Postgres 8.4數據庫。

我發現的所有文檔都表明這應該起作用。有任何想法嗎?

感謝, 阿拉斯泰爾

回答

5

Postgres SELECT for update語法僅提供了不等待如果無法立即獲取鎖定的選項。見postgres文檔。

要防止操作等待其他事務處理爲 提交,請使用NOWAIT選項。對於NOWAIT,如果立即無法鎖定所選行 ,則該語句會報告 錯誤,而不是等待。請注意,NOWAIT僅適用於行級鎖 - 所需的ROW SHARE表級鎖仍採用普通的 方式(請參見第13章)。如果您需要在不等待的情況下獲取表級鎖,則可以先使用NOWAIT選項LOCK, 。

當Postgres的工作,我已經觀察到,對於超時超過0的任何值將導致休眠發出SELECT FOR UPDATE但是當超時爲0,將發行SELECT FOR UPDATE NO WAIT

+0

雖然不是我期待的答案,但看起來與我見過的一致 - 謝謝! – Alastair

+1

如果您不在屬性文件中將javax.persistence.lock.timeout設置爲零,則查詢僅在執行「FOR UPDATE」時執行。如果您將其設置爲零(如我所說),則執行「FOR UPDATE NOWAIT」。 –

+0

至少在Hibernate 4.3.x和JPA 2.1中,您可以在查詢級別指定這些設置。無論是在@NamedQuery(通過hints屬性)還是在通過entityManager.createQuery(CriteriaBuilder.createQuery(Entity ...))使用setHint(...)創建的查詢中。 – gkephorus

0

將這個在你的persistence.xml:

<property name="javax.persistence.lock.timeout" value="0"/> 

或致電第一鎖定之前設置屬性。

+0

嗨馬爾西奧,感謝,但事實上也沒有這個無論是作爲一個persistence.xml變量或作爲第一個鎖的屬性。 – Alastair