1

I hope someone can clarify the below scenerio for me.

From what I understand, when you request a 'row' from hibernate, for example:

User user = UserDao.get(1);

I know have the user with id=1 in memory.

In a web application, if 2 web pages request and load the user at the same time, and then both update a property on the user's object, what will happend? e.g.:

user.pageViews += 1; // the value is current 10 before the increment
UserDao.update(user);

Will this use the value that is in-memory (both requests have the value 10), or will it use the value in the database?

4

2 に答える 2

2

2 人のユーザーに対して 2 つの休止状態セッションを使用する必要があります。これは、メモリ内にオブジェクトのインスタンスが 2 つあることを意味します。休止状態セッションを 1 つだけ (つまり、メモリ内のオブジェクトのインスタンスを 1 つ) しか使用しない場合、結果は予測できません。

同時更新の場合、2 番目の更新が優先されます。最初の更新の値は、2 番目の更新によって上書きされます。最初の更新が失われないようにするために、通常はバージョン カラムを使用し (hibernate のドキュメントを参照)、2 回目の更新でエラーが発生します。これをキャッチして対応することができます (たとえば、"Your record was modified in再ロードしてください」というメッセージが表示され、2 番目のユーザーが変更されたレコードで変更をやり直して、変更内容が失われないようにすることができます。

あなたの例のようにページビューカウンターの場合、別の解決策として、ページビューを順番にカウントする同期メソッドを書くことができます。

于 2012-09-25T15:28:27.870 に答える
1

デフォルトでは、in memory値が更新に使用されます。

User以下では、Web ユーザー インターフェイスのを変更するのではなく、自動ページ ビュー カウンターを実装することを想定しています。これが必要な場合は、Hibernate の楽観的ロックをご覧ください。

したがって、ページ ビューをカウントするときに 100% の精度が必要であると仮定すると、テーブル行の排他性を取得するために値をUser変更している間、エンティティをロックできます。pageView

Session session = ...
Transaction tx = ...

session.lock(user, LockMode.UPGRADE);
user.increasePageViews();

tx.commit();
session.close();

はデータベース内でLockMode.UPGRADE変換されるSELECT ... FOR UPDATEため、アプリケーションのスケーラビリティに影響を与えないように、ロックをできるだけ少なく維持するように注意してください。

于 2012-09-25T15:47:58.127 に答える