2017-03-01 10 views
1

IはCrudRepositoryを拡張私のインターフェースでこの方法を持っています。私は何を期待スプリングデータPESSIMISTIC_WRITE戻る古いDB値

(私は私のDBに残っ1つのバウチャーを持っていることを前提としてい):

の1-サービスAとB VoucherFetchComponent

2 - サービスA(のフェッチ()メソッドを呼び出しますまたはB)行をロックし、フィールドの1つを更新して返します。

3他のサービスはロックされた行にアクセスできるようになりました。しかし、クエリは指定された条件(used = false)と一致しないため、nullを返します。

私はちょうど

上記

、3-よう

1と2を得る他にどのようなサービスは、パラメータ(偽=使用)を持っていますが、それは以前に更新されていた古いオブジェクトを返します!

答えて

1

あなたが@Lockのjavadocを注意深く見ればそれはと述べている:注釈は クエリを実行するときに使用するLockModeTypeを指定するために使用

したがって、ロックはクエリの実行中にのみ有効です。クエリが終了すると、ロックが解除されます。それはあなたが期待しているように、トランザクション全体の期間はアクティブではありません。私は、標準的なロック機構を使用することをお勧めし

VoucherRepository

public void lock(Voucher voucher, LockModeType lockType){ 

entityManager.lock(voucher, lockType); 

VoucherFetchComponent

public Voucher fetch(Product product) { 
    Voucher voucher=voucherRepository.findTop1ByUsedFalseAndProductOrderByIdAsc(product); 
    if(voucher==null) 
     return null; 
    voucherRepository.lock(voucher, LockModeType.PESSIMISTIC_WRITE); 
    voucher.setUsed(true); 
    voucherRepository.save(voucher); 
    return voucher; 
} 

トランザクションが終了すると、ロックが解除されます。

+0

進捗はありません。 2番目のサービスがsave()メソッドを呼び出してエンティティを更新したい場合、OptimisticLockExceptionがスローされます。 findTop1ByUsedFalseAndProductOrderByIdAscメソッドが同じ値を返さないようにしたい – MoeKav

+0

メソッドがロックされたエンティティをクエリしようとすると、ロック例外が発生します...それらを処理する標準的な方法は、try {catch {トランザクションメソッドを実行し、例外を再試行してください(トランザクションはロールバックされ、新しいトランザクションを開始する必要があります)。ロックが解除されると、2番目のサービスがメソッドに入り、nullが返されます。 –

関連する問題