我想在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數據庫。
我發現的所有文檔都表明這應該起作用。有任何想法嗎?
感謝, 阿拉斯泰爾
雖然不是我期待的答案,但看起來與我見過的一致 - 謝謝! – Alastair
如果您不在屬性文件中將javax.persistence.lock.timeout設置爲零,則查詢僅在執行「FOR UPDATE」時執行。如果您將其設置爲零(如我所說),則執行「FOR UPDATE NOWAIT」。 –
至少在Hibernate 4.3.x和JPA 2.1中,您可以在查詢級別指定這些設置。無論是在@NamedQuery(通過hints屬性)還是在通過entityManager.createQuery(CriteriaBuilder.createQuery(Entity ...))使用setHint(...)創建的查詢中。 – gkephorus