java - redis中java的setIfAbsent(K,V, ExpiryTimeout)是原子的吗?

标签 java redis spring-data-redis

根据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():

https://github.com/spring-projects/spring-data-redis/blob/2.6.4/src/main/java/org/springframework/data/redis/core/DefaultValueOperations.java#L379

LettuceConverters.toSetArgs(过期,选项):

https://github.com/spring-projects/spring-data-redis/blob/2.6.4/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceStringCommands.java#L139

args.nx():

https://github.com/spring-projects/spring-data-redis/blob/2.6.4/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConverters.java#L800

关于java - redis中java的setIfAbsent(K,V, ExpiryTimeout)是原子的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72400507/

相关文章:

spring - Caused by : org. springframework.dao.IncorrectResultSizeDataAccessException: 不正确的结果大小:Spring Data Redis

spring - 在Kubernetes中部署Redis的Spring boot应用--Jedis Connection Refused错误

java - Eclipse 断点未绑定(bind)到正确的二进制文件

spring - 使用 Redis 修改 Spring session 中的前缀键

java - 如何从 Android 中的 TextView 中删除最后一个字符?

ruby-on-rails - Controller 中的查询缓存

Redis:我是否错误地使用了sismembers?

java - 使用 spring redis 存储库检索存储的 POJO 的 TTL

java - 有没有一种方法可以返回泛型父类(super class)型而无需在 Java 中进行强制转换?

java - 检测同根词