Избегайте повторяющихся строк через редиссон

У меня есть стол, Фу. Я добавляю строки в эту таблицу при определенных событиях. Текущий общий дизайн таков, что нельзя избежать дублирования сообщений. Это приводит к добавлению повторяющихся строк в таблицу.

Я не могу наложить уникальное ограничение на таблицу, так как есть разные типы сообщений, которые становятся строками в этой таблице. Я хочу избежать дублирования только для определенного типа сообщения.

Поскольку дублирующиеся сообщения часто приходят одновременно, и это приложение работает на нескольких узлах, я решил использовать Radisson для выполнения распределенной блокировки. Однако, похоже, это не работает. Я все еще получаю дубликаты строк в таблице.

Повторяющиеся сообщения обнаруживаются на основе идентификатора пользователя, даты и типа. Ниже приведен минималистичный демонстрационный код. Я пытаюсь выполнить чтение перед записью, и это чтение происходит в синхронизированном блоке между узлами приложения.

Цените любые вклады по этому вопросу.

     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();
     }

2 ответа

Я нашел проблему. Вышеуказанный блок кода был внутри @Transactional. С весенним уровнем изоляции по умолчанию это было REPEATABLE_READ в mysql. Взятие блокировки за пределы транзакции решило проблему.

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

В соответствии с этой частью кода вы рассматриваете userId, date и type как уникальные критерии, чтобы решить, можете ли вы вставить эту запись. Можете ли вы объяснить, почему вы не можете объединить их в одно целое?

Другие вопросы по тегам