加锁主要是将多客户端线程调用相同业务方法转换为串行化处理,比如多个客户端调用同一个方法对某个键自增(这里不考虑其它方法或业务会对该键同时执行自增操作) 调用SETNX命令对某个键进行加锁(如果获取锁则执行后续RMW操作,否则直接返回未获取锁提示) 执行RMW业务操作 调用DEL命令删除锁
假如某个客户端在执行了SETNX命令加锁之后,在后面操作业务逻辑时发生了异常,没有执行 DEL 命令释放锁。
该锁就会一直被这个客户端持有,其它客户端无法拿到锁,导致其它客户端无法执行后续操作。
解决思路:给锁变量设置一个过期时间,到期自动释放锁
SET key value [EX seconds | PX milliseconds] [NX]
如果客户端 A 执行了 SETNX 命令加锁后,客户端 B 执行 DEL 命令释放锁,此时,客户端 A 的锁就被误释放了。如果客户端 C 正好也在申请加锁,则可以成功获得锁。 解决思路:加锁操作时给每个客户端设置一个唯一值(比如UUID),唯一值可以用来标识当前操作的客户端。在释放锁操作时,客户端判断当前锁变量的值是否和唯一标识相等,只有在相等的情况下,才能释放锁。(同一客户端线程中加锁、释放锁) SET lock_key unique_value NX PX 10000
local current current = redis.call("incr",KEYS[1])
if tonumber(current) == 1
then redis.call("expire",KEYS[1],60)
end
redis-cli --eval lua.script keys , args
原文:https://www.cnblogs.com/gossip/p/13901425.html