Избегайте повторяющихся строк через редиссон
У меня есть стол, Фу. Я добавляю строки в эту таблицу при определенных событиях. Текущий общий дизайн таков, что нельзя избежать дублирования сообщений. Это приводит к добавлению повторяющихся строк в таблицу.
Я не могу наложить уникальное ограничение на таблицу, так как есть разные типы сообщений, которые становятся строками в этой таблице. Я хочу избежать дублирования только для определенного типа сообщения.
Поскольку дублирующиеся сообщения часто приходят одновременно, и это приложение работает на нескольких узлах, я решил использовать 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 как уникальные критерии, чтобы решить, можете ли вы вставить эту запись. Можете ли вы объяснить, почему вы не можете объединить их в одно целое?