私のWebアプリケーションでは、Hibernateでオプティミスティック(バージョニング)とペシミスティックロックを実装することに決めた理由で、同じデータに同時にアクセスするスレッドがいくつかあります。時々私はStaleObjectException
取得しています、しかしエンティティを正しくロックしてリロードする方法
@Transactional
public void doSomething(entity) {
session.lock(entity, LockMode.UPGRADE);
session.refresh(entity);
// I change the entity itself as well as entites in a relationship.
entity.setBar(...);
for(Child childEntity : entity.getChildren()) {
childEntity.setFoo(...);
}
}
@:
は現在、私は、エンティティをロックし、(@Transactionalとスプリングストランザクションマネージャとトランザクション区分を使用して)、その上に書き込み操作を実行するには、次のパターンを使用しますTransactionalは、ChildEntityが同時に変更され、間違ったバージョンを持つことを示すフラッシングです。
entity
とその子どもたちが正しくリフレッシュされていないと思いますので、古いデータで作業しています。誰かがこれを達成する方法を指摘できますか?私のいくつかの考えには、永続コンテキスト(セッション)をクリアするか、session.lock(entity, LockMode.READ)
を再度呼び出すことが含まれていましたが、ここで何が正しいかわかりません。
ありがとうございました!
"SELECT ... FOR UPDATE"をサポートするMySQL InnoDBを使用していますので、ここでは問題はありません。さらに、同時に変更が行われたときに「通知」を得るために、私はオプティミスティック・ロックも使用しています。 – Erik
申し訳ありませんが、あなたが子供に問題があるという点を忘れています(これは太字です:)。私は答えを更新しました... – Stas
私のコードでは、エンティティを常にロックしますが、エンティティを更新するのは子供だけではありません。したがって、ロックが取得される必要があります。私の主な関心事は、リフレッシュだけを使って最新のエンティティ/子どもたちと一緒に作業していないということです。 – Erik