2

次のコード サンプルでは:

   Session session = getSessionFactory().openSession();

   MyObject currentState = (MyObject) 
           session.get(MyObject.class, id, new LockOptions(LockMode.???));

   if (!statusToUpdateTo.equals(currentState.getStatus())) {
     tx = session.beginTransaction();

     currentState.setStatus(statusToUpdateTo);
     session.save(currentState);

     tx.commit();
   }

   session.close();

コードからうまく解釈できると思いますが、アイデアはストアをチェックして、特定の ID を持つオブジェクトを見つけ、それを特定のステータスに更新することです。オブジェクトがすでに更新したいステータスになっていることがわかった場合は、何もしません。それ以外の場合は、ステータスを更新してストアに保存します。

私が心配しているのは、これらのリクエストのいくつかが一度に届き、すべてが同じオブジェクトを読み取って更新しようとした場合はどうなるかということです。doco を見ると、Hibernate は「通常、正確なロック レベルを自動的に取得する」ように見えます。(LockMode.class) ですが、オブジェクトを読み取り、更新する必要があると判断し、更新することができるのは 1 つだけであることを確認したいと考えています。他のスレッドが同じデータベース エントリに対して同じことを行う必要はありません。

LockMode クラスから、私が求めているのは PESSIMISTIC_WRITEだと思いますが、これを確認するドキュメント リソースが見つからないようです。誰かが私のためにこれを確認できますか?上記のコードは私が求めていることを実行しますか?

4

1 に答える 1

4

そのため、元のコードで、セッションを閉じたときに、挿入した行を削除するための後続の呼び出しが tx.commit() が呼び出されたときに完了しなかったため、データベースにロックが残っていることに気付きました。

次のelseブロックを追加した後、ロックが解放されたことを意味すると推測するテストに合格します(これらの行は現在クリーンアップされているため)。

   Session session = getSessionFactory().openSession();

   MyObject currentState = (MyObject) 
           session.get(MyObject.class, id, 
                       new LockOptions(LockMode.PESSIMISTIC_WRITE));

   if (!statusToUpdateTo.equals(currentState.getStatus())) {
     tx = session.beginTransaction();

     currentState.setStatus(statusToUpdateTo);
     session.save(currentState);

     tx.commit();
   } else {
     // Seems to clear lock
     tx = session.beginTransaction();
     tx.rollback();
   }

   session.close();

私には、これは明らかに Hibernate のロック メカニズムについての私の理解不足を反映していますが、session.get(...) または session.load(...) を使用してロックを取得し、それから解放しないのは少し奇妙に思えます。セッション自体を使用してロックしますが、トランザクションを作成してコミット/ロールバックすることによってのみロックします。

もちろん、観察された動作を誤解している可能性があります:)

于 2013-09-13T04:14:02.560 に答える