GETSET 与 SET GET 是什么
GETSET 一次完成两件事:写入新值并返回旧值,整个过程原子完成,常用于「读取并重置」类逻辑,例如计数器换代或抢锁前读取上一次状态。自 Redis 6.2 起 GETSET 被标记为废弃,官方推荐用 SET key value GET,因为它不仅效果相同,还能同时叠加 NX、XX、EX、KEEPTTL 等选项,表达力更强。
基本信息
| 旧命令 | GETSET key value(6.2 起标记废弃,仍可用) |
|---|---|
| 推荐写法 | SET key value GET [NX|XX] [EX|PX|KEEPTTL] |
| 原子性 | 两种情况都在单条命令内完成读写 |
| 返回旧值 | 键不存在时返回 nil,但值已经被写入 |
| 适用类型 | 仅字符串类型;其他类型会报类型错误 |
典型使用场景
- 计数器换代:写入新周期计数前先取回上一周期的值
- 状态重置:读取旧状态并立刻置为初始值,避免两次往返
- 幂等标记:用 SET NX 组合替代「先判断再写」的竞态写法
- 抢锁前读取:先取回旧持有者信息再写入自己的标识
- 迁移到新写法:把旧代码里的 GETSET 逐步换成 SET GET,同时获得选项组合能力
新旧写法对比
新旧写法对比
# 旧写法:键不存在时返回 nil,但值已经写进去了
GETSET counter 1 # -> (nil),此时 counter = 1
GETSET counter 2 # -> 1,此时 counter = 2
# 推荐写法:效果相同,还可以叠加过期时间等选项
SET counter 3 GET # -> 2
SET counter 4 GET EX 60 # 返回 3,并设置 60 秒过期
# 只在新键上写入并返回旧值
SET counter 5 GET NX
# 检查当前值
GET counter写法对照
| 写法 | 返回 | 可叠加选项 |
|---|---|---|
| GETSET key value | 旧值;键不存在返回 nil | 无 |
| SET key value GET | 旧值 | NX / XX / EX / PX / KEEPTTL |
| SET key value | OK | 同上 |
| SET key value NX | OK 或 nil(未写入) | 同上 |
用返回 nil 判断「键是否存在」时要小心:GETSET 与 SET GET 在键不存在时不但返回 nil,还会把新值写进去,判断与写入是同一动作。
新代码统一使用 SET ... GET:旧命令虽然仍可执行,但在启用命令审计或受限 ACL 的环境里可能被直接禁用,迁移期越短越好。