Postgres データベースに対して Hibernate 3 を介して、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 はロックを取得するために最大 5 秒間 (5000 ミリ秒) 試行し、その後例外をスローする必要がありました。代わりに、コードはデッドロックになります。
これを 2 つの異なるスレッドで実行すると、スレッド 1 (em1) が解放するとすぐにスレッド 2 (em2 を使用) がロックを取得することがわかります。そのため、ロックが発生していますが、タイムアウトすることはありません。
PESSIMISTIC_WRITE や任意のタイムアウト値 (2ms、0ms 'NO WAIT') などでも同じ効果が得られます。
Hibernate 3.6.10 Final (最新の Hibernate 3 バージョン) と Postgres jdbc ドライバー 9.2-1003.jdbc4 (最新のドライバー) を使用しています。Postgres 8.4 データベースに対して実行しています。
私が見つけたすべてのドキュメントは、これが機能することを示唆しています。何か案は?
ありがとう、アラステア