*Redis WATCH 命令

监视一个或多个 key,若在 EXEC 执行前这些 key 被其他客户端修改,则事务失败。


*语法

WATCH key [key ...]

*参数说明

参数 类型 必填 说明
key String 要监视的键名,可多个

*返回值

总是返回 OK


*时间复杂度

O(1) 每个 key。


*示例

# 客户端 A
> WATCH balance:1001
OK
> MULTI
OK
> DECRBY balance:1001 100
QUEUED
> SADD transactions:1001 "tx001"
QUEUED
> EXEC
(nil)   # 客户端 B 在此期间修改了 balance:1001

# 客户端 B(在客户端 A WATCH 和 EXEC 之间)
> DECRBY balance:1001 50
(integer) 450

*常见错误

错误 原因 解决
WATCH 后未执行 MULTI 单独 WATCH 无意义 确保 WATCH 后尽快进入 MULTI/EXEC
WATCH 过多 key 增加冲突概率 仅 WATCH 真正需要原子性的 key
长时间 WATCH 不 EXEC 事务失败概率上升 缩短 WATCH 到 EXEC 的时间窗口

*最佳实践

  1. 乐观锁 CAS:读取数据 → WATCH → 业务计算 → MULTI → 写入 → EXEC。冲突则重试。
  2. 监控关键 key:只 WATCH 真正需要原子性的 key,减少冲突概率。
  3. 自动重试:业务层封装 WATCH/MULTI/EXECEXEC 失败自动重试 N 次。

  4. 缩短 WATCH 窗口:WATCH 到 EXEC 的时间应尽量短,不要在中间执行耗时操作或网络请求。

*5. 幂等性设计:事务中的命令应设计为幂等,重试时不会因重复执行产生副作用。

*FAQ

Q1: WATCH 后多久失效? A: WATCH 持续到 EXECDISCARD 调用为止。连接断开也自动取消。

Q2: WATCH 和锁有什么区别? A: WATCH 是乐观锁(检测冲突而非阻塞),不会阻塞其他客户端修改。冲突时事务失败,需重试。

Q3: 如何取消 WATCH? A: UNWATCH 取消所有监视;EXECDISCARD 也会自动取消。

Q4: WATCH 可以跨多个 key 吗? A: 可以。WATCH 支持多个 key,任意一个 key 被修改都会导致事务失败。

Q5: WATCH 对过期 key 有效吗? A: 有效。如果 WATCH 的 key 在 EXEC 前过期,EXEC 会返回 nil(事务失败)。