1

Hibernateを使用するWebアプリケーションがあるとしましょう。私の質問は、異なるユーザーからの2つの異なるトランザクションが同じエンティティにアクセスして操作した場合、どうなるかについてです。たとえば、「Student」という名前のエンティティがあり、フィールドは「age」です。ここで、異なるユーザーからの2つの異なるトランザクションで、Hibernateセッションを使用してそのエンティティをフェッチします。例:

Student student = session.load(1); // 1 is the id of some student

次に、1人のユーザーが年齢フィールドを操作します。例:student.setAge(12); 2番目のユーザーは、完全に別のトランザクションでその変更を確認しますか?つまり、2番目のユーザーが自分のトランザクションstudent.getAge()を呼び出すと、新しい値-12が表示されますか?ageプロパティを変更した最初のユーザーは、まだトランザクションをコミットしていないことに注意してください。

4

3 に答える 3

1

それは部分的に冬眠中の質問です。コミットされていないデータが他のユーザーに表示されるかどうかは、データベース接続の分離レベルをコミットされていない読み取りに変更したかどうかによって異なります。あなたがそれをしたいと思う正当な理由はそれほど多くありません.hibernateは、オーバーライドされない限り、デフォルトでread-committedになります。したがって、一般的に、いいえ、トランザクションがコミットされるまで、他のユーザーには変更が表示されません。

分離レベルを下げた場合は、SQL が実際にデータベースに送信されるタイミングになります。これは、休止状態のフラッシュ設定に基づいており、多層システムでは予測が少し難しい場合があります。しかし、基本的に呼び出しsetAgeは、他の人が見ることができるデータベースに SQL を送信するつもりはありません。フラッシュを引き起こす何かが発生する必要があります。それらが何であるかは、やはり構成に依存します。

さらに、更新がコミットされる前に 2 番目のセッションがエンティティをロードした場合、最初のセッションが更新をコミットしたとしても、明示的に更新を呼び出さない限り、その 2 番目のセッションはメモリ内エンティティを自動的に更新しないことに注意してください。例えば、

Time 1: Session A loads Student 1
Time 2: Session B loads Student 1
Time 3: Session A sets new age and commits
Time 4: Session B gets Age, will still see old value
Time 5: Session B calls refresh on Student 1
Time 6: Session B gets Age, will see new value set in Session A
于 2013-03-01T20:47:34.187 に答える
0

この場合のように、Hibernate は複数のスレッドで同時に更新するのが得意です。

まず、この場合、スレッドセーフの問題は存在しません。各トランザクションは独自のセッションを保持するため、各セッションはロードされたオブジェクトをいわゆる第 1 レベル キャッシュにそれぞれ保持します。2 つのスレッドの 2 つのインスタンスはお互いを認識しません。

次に、複数のトランザクションが同じレコードを更新する場合、楽観的ロック メカニズムが機能します。早い者勝ちモデルです。最初にコミットされたトランザクションが成功すると、2 番目にコミットされたトランザクションは例外をスローして失敗します。hibernate は versin プロパティをチェックして、更新操作がコミットされる前にバージョンが元のバージョンであるかどうかを確認するためです。

http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/transactions.htmlを参照

于 2013-03-05T02:16:23.063 に答える