20

Hibernateのセッションがスレッドセーフであるかどうかを知る必要があります。しかし、明らかに、実行のためにすべてのスレッドに新しいセッションがアタッチされます。しかし、私の質問は、あるスレッドでエンティティの値を更新した場合、それは同時に実行中に他のスレッドに反映されるのでしょうか?

私の問題は、2つのスレッドから順番に更新を実行すると、値が適切に更新されますが、更新をほぼ完全に実行すると失敗します。

たとえば。テーブルの現在のステージ。

  ID      NAME      MARKS
------- --------- --------
  1       John       54

私は次のことをしようとしています:

Student student = session.load(Student.class, 1);
student.setMarks(student.getMarks() + 1);
session.update(student);
session.close();

上記のコードをループ、たとえば10で実行しようとすると、テーブル「student」の「marks」の値が適切に更新されます。つまり、値が適切な64に更新されます。

しかし、スレッド環境で同じコードを実行しようとすると、悪い結果になります。

4

4 に答える 4

24

実装者がスレッドセーフであることは意図されていません。代わりに、各スレッド/トランザクションは、SessionFactory から独自のインスタンスを取得する必要があります。

これを念頭に置いても、トランザクションが発生するため、動作が期待どおりにならない可能性があります。適切なトランザクション分離レベルを設定する必要があります。構成ガイドhibernate.connection.isolationプロパティーを参照してください。

于 2010-09-23T11:29:32.187 に答える
20

Hibernate セッションとスレッドは混在しません。

一度に複数のスレッドからのセッションを使用しないでください。単一のスレッドからのセッションのみを使用することをお勧めします。DB セッションの実装は、アドセーフである必要さえありません。

また、複数のスレッドで処理を開始したときにトランザクションがどうなるかも考慮する必要があります。トランザクションは現在のスレッドに関連付けられています。これはすぐに気が遠くなり、実装者が製品をテストしていない領域に入ります。

結局、人生は短すぎて、その沼地で迷子になることはできません。

于 2010-09-23T11:32:53.533 に答える
4

Hibernate セッションはスレッドセーフではありません。各スレッドのセッションを作成するには、TheadLocal クラスを使用します。

 private static ThreadLocal<Session> threadSafeSession = new ThreadLocal<Session>() {
    protected Session initialValue(){
    return sf.openSession();
      }
    };

あなたのメソッドでは、各スレッドのセッションを次のように取得します:-

Session session = threadSafeSession.get();
于 2015-08-09T07:04:06.627 に答える