Files
spring-boot-demo/redis/docs/08-ttl.md
T

2.4 KiB

Home | Prev: Pub/Sub | Next: Redis as the Spring cache

8. TTL: setting it, reading it, and losing it

13-ttl.txt drives StringRedisTemplate and checks the server with redis-cli.

Reading a TTL

getExpire(key) returns seconds, with two special values that are easy to misread as errors:

Value Meaning
-1 The key exists and has no TTL
-2 The key does not exist

Redis rounds TTL to the nearest second (a fresh 10-minute TTL reads 600). The template's getExpire(key, TimeUnit) converts, and the conversion truncates: the same key, read a moment later, gave 600 seconds and 9 minutes.

Setting one

  • opsForValue().set(key, value, Duration) sets value and TTL in one command, so there is no window in which the key exists without a TTL.
  • Duration.ofMillis(1500) is honoured (getExpire(key, MILLISECONDS) is at most 1500); getExpire(key) in seconds reads 1.
  • expire(key, Duration) sets a TTL on an existing key; persist(key) removes it.

The trap: a plain set throws the TTL away

set("session", "v1", Duration.ofMinutes(10))   -> TTL 600
set("session", "v2")                           -> TTL -1

Overwriting a key with a plain SET clears its TTL. If you refresh a cached value, pass the TTL again, or overwrite with Expiration.keepTtl() (the KEEPTTL option), which the transcript shows leaving the TTL at 600.

setIfAbsent with a TTL

setIfAbsent("lock:job", "worker-1", Duration.ofSeconds(30)) is a SET with the NX option and a 30-second expiry: the first caller gets true, the second false, and the key disappears by itself if the holder dies. It is the smallest useful lock. It is not a complete distributed-lock recipe (no owner-checked release, no fencing), and this repository does not test one.

Expiry is real

The transcript sets a 300 ms TTL, reads the value, waits until get returns null, and confirms with EXISTS blink returning 0.

Going deeper

Home | Prev: Pub/Sub | Next: Redis as the Spring cache