根据documentation , spring data redis 的 setIfAbsent(K, V)
使用setNX
命令。然而,setIfAbsent(K, V, Expiry timeout)
seems to use set
命令,而不是 setNX
。这是否意味着必须在键、值上设置超时使其不是原子的?
在我的用例中,我想为每一行设置 TTL,并且我试图了解如果两个线程(或应用程序实例)调用 setIfAbsent(K,V, sometimeoutinminutes)
,redis 将如何表现。同时?是只有一个请求更新 key (setNX
行为)还是两者都更新 key ?
查看implementation ,我可以看到两者的代码路径略有不同,所以这让我想知道后者是否真的是原子的。
我的代码如下所示:
@Bean
public RedisTemplate<?, ?> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<?, ?> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
return template;
}
code that updates:
//try to get value for a given key from redis.
String value = redisTemplate.opsForValue().get(key);
//if present, return value to the caller.
if (value != null) {
return value;
}
//if not, fetch value from remote.
value = makeNetworkCallToGetValue(key);
if (value != null) {
// update redis. what happens if 2 threads/application instances call this at the same time?
redisTemplate.opsForValue().setIfAbsent(key, value, Duration.ofMinutes(1));
}
return value;
库版本:spring-data-redis:2.6.4
最佳答案
3 参数和 4 参数 setIfAbsent()
重载将参数 SetOption.ifAbsent()
传递给 connection.set()
。这似乎将 NX
填充到 redis SET
命令中,类似于 connection.setNX()
的操作。我猜他们想重构这种方法,以减少支持 SET
的选项和参数的所有组合所需的方法重载数量。
SetOption.ifAbsent()
:
LettuceConverters.toSetArgs(过期,选项)
:
args.nx()
:
关于java - redis中java的setIfAbsent(K,V, ExpiryTimeout)是原子的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72400507/