从 Redis 版本 6.2.0 开始,此命令被视为已弃用

在迁移或编写新代码时,可以将其替换为带有 `GET` 参数的 `SET` 命令。

从 Redis 版本 6.2.0 开始,此命令被视为已弃用
在迁移或编写新代码时,可以将其替换为带有 GET 参数的 SET 命令。

语法

1
GETSET key value

可用版本

≥ 1.0.0

时间复杂度

$O(1)$

ACL 类别

@write, @string, @fast

原子地将 key 设置为 value,并返回存储在 key 中的旧值。当 key 存在但存储的值不是字符串类型时返回错误。成功的 SET 操作会丢弃与键关联的任何过期时间。

返回值

返回存储在 key 中的旧值。 当 key 没有旧值(即 key 不存在)时,返回 nil

当 key 存在但存储的值不是字符串类型时,返回错误。

设计模式

GETSET 可以与 INCR 一起使用,用于原子重置计数。例如:进程可能会在每次发生某些事件时针对键 mycounter 调用 INCR,但有时我们需要获取计数器的值并将其自动重置为零。这可以使用 GETSET mycounter "0" 来完成:

1
2
3
4
5
6
7
redis> INCR mycounter
(integer) 1
redis> GETSET mycounter "0"
"1"
redis> GET mycounter
"0"
redis>

示例 1

对设有过期时间,且存储值为字符串类型的 key 进行 GETSET 操作:

1)设置键 name 的值为 “John”,并设置过期时间为 600 秒。

2)获取 name 的剩余过期时间,此时是 595 秒。

3)以新值 “Johnson Lin” 替换旧值 “John”,并返回旧值 “John”。

4)因为使用了 GETSET 命令,所以 name 的过期时间被删除,此时 name 没有过期时间,返回 -1。

1
2
3
4
5
6
7
8
9
redis> SET name "John" EX 600
OK
redis> TTL name
(integer) 595
redis> GETSET name "Johnson Lin"
"John"
redis> TTL name
(integer) -1
redis>

示例 2

对存储值为 list 类型的 key 进行 GETSET 操作,返回 WRONGTYPE Operation against a key holding the wrong kind of value 错误:

1
2
3
4
5
6
7
redis> LPUSH list_key "Rain rain"
(integer) 1
redis> TYPE list_key
list
redis> GETSET list_key "Go go"
(error) WRONGTYPE Operation against a key holding the wrong kind of value
redis>

示例 3

对不存在的 key 进行 GETSET 操作,结果返回 nil

1
2
3
4
5
redis> EXISTS foo
(integer) 0
redis> GETSET foo "Rain"
(nil)
redis>

(END)