使用redis实现分布式锁一、
SETNX
- 语法:
SETNX key value
- 将 key 的值设为 value ,当且仅当 key 不存在。
- 若给定的 key 已经存在,则 SETNX 不做任何动作。
- SETNX 是『
SET if Not eXists
』(如果不存在,则 SET)的简写 - 该命令仅当key不存在时才可以设置成功,使用该命令设值可以
保障众多客户端中只有一个客户端可以成功设置值(即:获取到锁)
SETNX lock lock_value
释放锁就比较简单,只需要将此key删除掉,其他客户端就可以继续为此key设值从而获取到锁
DEL lock
但是如果仅用上述命令实现加锁时,那么一般释放锁的操作也就是DEL KEY;假如某客户端在准备释放锁时发生异常或者突然宕机,那么这个锁将不会被释放,进而引起其他客户端无法获取到锁
所以在获取锁时,需要给锁设置一个过期时间,可能最初加锁会这样设计
SETNX lock lock_value
>ok
#设置过期时间
EXPIRE lock 5
上述实现还是会出现问题,由于上述两命令不是一个原子操作
,假如当加锁成功,但是在设置过期时间的同时服务器突然挂了或者其他原因导致未设置成功,依然无法解决
好在redis2.8之后给set命令提供了更多的参数用来在一个原子操作中
完成setNx key value和expire key
两个命令的结合
SET
- 语法:
SET key value [EX seconds] [PX milliseconds] [NX|XX]
EX second
:设置键的过期时间为 second 秒。 SET key value EX second 效果等同于 SETEX key second value 。PX millisecond
:设置键的过期时间为 millisecond 毫秒。 SET key value PX millisecond 效果等同于 PSETEX key millisecond value 。NX
:只在键不存在时,才对键进行设置操作。 SET key value NX 效果等同于 SETNX key value 。XX
:只在键已经存在时,才对键进行设置操作