У меня есть некоторые проблемы с использованием Spring Data Redis для создания распределенной блокировки. Для этого используется метод putIfAbsent из CacheManager.
С точки зрения высокого уровня операция выглядит примерно так:
if (manager.putIfAbsent(parameters) == null) {
executeOperation();
}
Из реализации putIfAbsent кажется, что используется операция setNX из базового драйвера Jedis.
Код реализации Spring выглядит примерно так:
if (!connection.setNX(keyBytes, value)) {
return connection.get(keyBytes);
}
maintainKnownKeys(element, connection);
processKeyExpiration(element, connection);
setNX соединения — это просто делегирование фактической операции клиента. В реализации этого метода есть что-то вроде:
JedisConverters.toBoolean(jedis.setnx(key, value));
Итак, я столкнулся с двумя отдельными проблемами:
Мой executeOperation() был одновременно выполнен двумя отдельными процессами. (Всего несколько случаев этой проблемы).
Я дошел до ситуации, когда ключ остался и не просрочен. Это означает, что код processKeyExpiration(элемент, соединение) не был выполнен. Это означает, что setNx, выполненный как ключ, не был добавлен и возвращен перед этим оператором, но на самом деле ключ был добавлен.
Большую часть времени все работает нормально. Сериализатор ключей — StringRedisSerializer
.
Я использую: spring-data-redis 1.8.23.RELEASE jedis 2.9.3
Могут ли быть какие-то экологические проблемы, которые джедаи не решают должным образом, или что-то в этом роде? Кто-нибудь достиг чего-то подобного? Можно ли попробовать какое-либо исправление, обновление библиотеки?