Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B38FGKKam5SCGgwgduVAh3
55 lines
2.4 KiB
Markdown
55 lines
2.4 KiB
Markdown
[Home](../README.md) | Prev: [Pub/Sub](07-pub-sub.md) | Next: [Redis as the Spring cache](09-redis-as-cache.md)
|
|
|
|
# 8. TTL: setting it, reading it, and losing it
|
|
|
|
[13-ttl.txt](output/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
|
|
|
|
- [TtlTest](../src/test/java/com/ankurm/redis/TtlTest.java)
|
|
- [Redis EXPIRE](https://redis.io/docs/latest/commands/expire/) and [SET](https://redis.io/docs/latest/commands/set/)
|
|
- [Chapter 6](06-hash-ttl-and-keyspace-events.md) for TTL on `@RedisHash` entities
|
|
|
|
[Home](../README.md) | Prev: [Pub/Sub](07-pub-sub.md) | Next: [Redis as the Spring cache](09-redis-as-cache.md)
|