2017-05-15 39 views
0

私はテーブルFooを持っています。特定のイベントでこのテーブルに行を追加します。現在の全体的な設計は、重複するメッセージを避けることができないようなものです。これにより、テーブルに重複行が追加されます。redissonで重複する行を避ける

テーブルに一意の制約を付けることはできません。異なるタイプのメッセージがこのテーブルの行になるためです。私は特定のタイプのメッセージに対してのみ重複を避けたい。

重複するメッセージが頻繁に同時に発生し、そのアプリケーションが複数のノードで動作するため、私はradissonを使用して分散ロックをとることにしました。しかし、それは動作していないようです。私はまだテーブルに重複した行を取得しています。

重複したメッセージは、userId、日付、およびタイプに基づいて検出されます。以下は最小限のデモコードです。私は書き込みの前に読み込みをしようとしており、この読み込みはアプリケーションノード間の同期ブロックで起こっています。

これに関するすべての入力を気に入ってください。

 if(updateEntry.getType().equals(Type.XYZ) { 
     java.sql.Date date = updateEntry.getDate(); 
     String redisLockKey = "MyAPP" + "-" + userId+"-"+date.toString()+ "-" + "type-XYZ"; 
     RLock rLock = redissonClient.getLock(redisLockKey); 
     rLock.lock(5, TimeUnit.SECONDS); 
     MyEntity myEntity = myEntityRepository.findByUserIdAndDateAndActivityType(userId,date,Type.XYZ); 
     if(null == myEntity) { 
      myEntity = new MyEntity(); 
      // myEntity setters 
     myEntity = myEntityRepository.saveAndFlush(myEntity); 
     } 
     rLock.unlock(); 
    } 

答えて

0

問題が見つかりました。上記のコードブロックは@Transactionalの内側にあります。 springのデフォルトの分離レベルでは、mysqlではREPEATABLE_READでした。トランザクション外のロックを取ることで問題が解決されました。

0
MyEntity myEntity = myEntityRepository.findByUserIdAndDateAndActivityType(userId,date,Type.XYZ); 
if(null == myEntity) { 
    myEntity = new MyEntity(); 
    // myEntity setters 
    myEntity = myEntityRepository.saveAndFlush(myEntity); 
} 

このコードの部分では、このレコードを挿入できるかどうかを判断するためのuserId、日付、およびタイプを一意の基準として扱います。ですから、あなたはなぜそれらを3つにまとめることができないのかを説明することができますか?

関連する問題