According to the documentation, spring data redis's setIfAbsent(K, V)
uses setNX
command. However, setIfAbsent(K, V, Expiry timeout)
seems to useset
command, instead of setNX
. Does it mean that having to set timeout on a key,value makes it not atomic?
In my use case, I want to set TTL for each row and I'm trying to understand how redis would behave if two threads (or application instances) call setIfAbsent(K,V, sometimeoutinminutes)
at the same time? Does only one request update the key (setNX
behavior) or both update the key?
Looking at the implementation, I can see that both have slightly different code paths, so which makes me wonder if the latter is really atomic.
My code looks like this:
@Beanpublic 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;
Library version: spring-data-redis:2.6.4