2

フィールドの 1 つで @version を使用するエンティティがあります。2 つのトランザクションがこのエンティティを同時に変更すると、1 つが失敗し (楽観的ロック例外が発生し)、もう 1 つが成功するようにしたいと考えています。

このテストを単一の JVM で実行すると正常に動作しますが、クラスター環境で実行すると、2 つのトランザクションが成功し、楽観的ロックはスローされません。

public class DeploymentLock  {

    @Column(name = "DEPLOYMENT_COUNTER")
    private Long deploymentCounter;

    @Version
    @Column(name = "ENTITY_VERSION")
    private Long version;
    ...
}

私は何かを逃していますか?@Version で "@Generated(GenerationTime.ALWAYS)" を使用する必要がありますか?

ちなみに、アプリでSpringとhibrnateを使用しています...何か考えはありますか?

4

1 に答える 1

1

DeploymentLock2 つの異なるhibernate セッション (通常は 2 つの異なる JVM または 2 つの異なるホスト) 内に同じ値を持つ 2 つのインスタンスがversionある場合、呼び出す更新の 2 番目は をスローする必要がありますHibernateOptimisticLockingFailureException

基本的に休止状態は次のようなことをしています:

UPDATE DeploymentLock SET deploymentCounter = ..., version = 2 WHERE version = 1

次に、更新によって行が変更されなかった場合、例外がスローされます。

version2 つの異なる JVM (または 2 つのセッション) に、同じ値を持つ同じインスタンスがあると確信していますか? 予期しrefresh()ない場所があるか、競合状態が原因で 2 番目のインスタンス クエリが更新された を返している可能性がありますDeploymentLockか?

ロギングまたはprintlnデバッグを追加して、更新の直前にバージョン値を出力することもできます。バージョンが同じであることが示されている場合は、投稿を編集して、更新呼び出しをどのように行っているかを示すことができますか?

于 2012-06-05T16:40:39.407 に答える