首页/数据/数据库速查/GETSET 与 SET ... GET(旧值返回)
Redis 命令96 条

GETSET 与 SET ... GET(旧值返回)

GETSET 设置新值并返回旧值(原子);自 Redis 6.2 起被标记废弃,推荐用 SET key value GET 达到同样效果并支持 NX/EX 等选项。

数据库速查数据更新于 2026-10-13

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 valueOK同上
SET key value NXOK 或 nil(未写入)同上
用返回 nil 判断「键是否存在」时要小心:GETSET 与 SET GET 在键不存在时不但返回 nil,还会把新值写进去,判断与写入是同一动作。
新代码统一使用 SET ... GET:旧命令虽然仍可执行,但在启用命令审计或受限 ACL 的环境里可能被直接禁用,迁移期越短越好。

易错点

  • 用 GETSET 判断键是否存在:不存在的键也会被创建,返回 nil 不代表没有写入
  • 对 Hash、List 等类型使用:直接报类型错误,GETSET 与 SET GET 只作用于字符串
  • 以为 SET ... GET EX 会保留原有过期时间:设置 EX 会覆盖原有 TTL,需要保留时应使用 KEEPTTL
  • 在受限 ACL 环境依赖已废弃命令:命令可能被禁用导致业务失败,迁移期应尽快完成替换
  • 忽视原子性的边界:单条命令内读写是原子的,但「先 GETSET 再根据旧值做别的操作」的整体逻辑仍不是原子事务,跨命令的并发问题要用事务或函数解决

数据来源与参考

  • Redis 官方文档: GETSET
  • Redis 官方文档: SET

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌