【发布时间】:2019-10-29 14:06:34
【问题描述】:
我在使用 Spring Data Redis 创建分布式锁时遇到了一些问题。为此,它使用了 CacheManager 中的 putIfAbsent 方法。
从高层次的角度来看,操作看起来像这样:
if (manager.putIfAbsent(parameters) == null) {
executeOperation();
}
从 putIfAbsent 的实现看来,似乎使用了来自底层 Jedis 驱动程序的 setNX 操作。
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(element, connection) 没有被执行。这意味着在该语句之前没有添加并返回作为键执行的 setNx,但实际上添加了键。
大多数时候一切正常。
密钥序列化程序是StringRedisSerializer。
我正在使用: spring-data-redis 1.8.23.RELEASE 绝地武士2.9.3
会不会有一些环境问题没有得到正确处理 由 Jedis 或类似的东西?有没有人达到这样的程度?是否有任何可以尝试的修复程序,库更新?
【问题讨论】:
标签: java spring-boot redis jedis spring-data-redis