首页/数据/数据库速查/SETNX / SET NX 的区别与用法
Redis 命令96 条

SETNX / SET NX 的区别与用法

SETNX 是「不存在才设置」的历史命令:不能带过期,只能配合 EXPIRE;等价于 SET key value NX。锁与去重场景建议直接用 SET NX PX 一条原子完成。

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

SETNX 是什么

SETNX 是 SET if Not eXists 的缩写:仅当键不存在时写入,成功返回 1,键已存在返回 0 且不改动原值。它自身没有过期参数,所以锁与去重场景更推荐等价的 SET key value NX EX 秒(或 NX PX 毫秒),把判断存在、写入、设过期压成一条原子命令,中间不会被打断。

基本信息

适用版本Redis 2.6+;SET 支持 NX/EX 需 2.6.12 及以上
语法SETNX key value
返回值1=写入成功;0=键已存在,未做修改
等价写法SET key value NX
带过期写法SET key value NX EX 3600 / NX PX 5000

典型使用场景

  • 任务幂等去重:同一订单号只允许处理一次,写入成功的一方才继续
  • 获取分布式锁:NX 成功即持锁,配合 PX 过期防止持锁进程崩溃后死锁
  • 缓存预热互斥:并发请求里只放一个去回源加载,其余等待或返回旧值
  • 领券、抢购类防重复:以用户加活动维度做一次性标记
  • 定时任务防重叠:到点先抢占标记,避免上一轮没跑完就再起一个

两种写法对比

两种写法对比
SETNX job:sync:20261012 1        # 成功返回 1;已存在返回 0,键不变
EXPIRE job:sync:20261012 3600    # 必须补过期,且与上一条不是原子操作
TTL job:sync:20261012            # 确认过期时间是否真的设上了

SET job:sync:20261012b 1 NX EX 3600     # 一条命令搞定,推荐写法
SET lock:order:42 6f1d2c4e NX PX 5000   # 锁场景用毫秒级,秒级精度过粗
GET lock:order:42                       # 记下写入的 token,释放时要比对

返回值读法

返回值含义调用方动作
1键此前不存在,本次写成功视为抢到锁或首次执行,继续业务逻辑
0键已存在,未做任何修改区分他人持锁与重复任务,选择等待或直接返回
nil键不存在时的 GET 类返回确认命令拼写与连接是否指向正确实例
SETNX + EXPIRE 之间存在崩溃窗口:拿到键还没设过期就挂掉,键会永久残留(经典死锁成因);用 SET ... NX EX 单条原子命令规避。
SETNX 的语义是不存在才写,键已存在时不会刷新过期时间。续期必须显式调用 EXPIRE,或使用带看门狗的客户端库,不要指望再次 SETNX 能成功。

易错点

  • 用 SETNX 做锁却不设过期:持锁进程崩溃后锁永不释放,业务彻底卡死
  • SETNX 与 EXPIRE 分两条发且中间抛异常,键无过期时间长期残留
  • 把 SETNX 返回 0 一律当失败:它也可能是自己上一次操作的残留,需靠业务幂等键区分
  • 在哨兵或集群主从切换瞬间加锁,新主上没有该键,同一把锁被两人同时持有
  • 用秒级 EX 给极短任务加锁,粒度太粗导致正常任务被误判为持锁中

数据来源与参考

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

相关工具

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