1、锁一直有效 2、误删除其它请求创建锁
陷阱1:锁一直有效
多个请求到达,虽只有一个请求 SetNX 可成功,但任何Expire 都可成功,
即获取不到锁,也可刷新过期时间,如请求密集的话,过期时间一直被刷,导致锁一直有效。
解决:保证原子性同时,有条件执行 Expire,便有 Lua 代码:
2.6.12 起,set涵盖SETEX 的功能, SET 本身包含设置过期时间功能,前面需要功能只用 SET 就可
如上代码是完美的吗?答案是还差一点!设想一下
陷阱2:误删除其它请求创建锁
更新缓存 时间> 锁有效期还长,更新中,锁失效,另一个请求获取锁,误删其它请求创建锁
解:建锁时引入随机值:
补充:本文在删除锁的时候,实际上是有问题的,没有考虑到 GC pause 之类的问题造成的影响,比如 A 请求在 DEL 之前卡住了,然后锁过期了,这时候 B 请求又成功获取到了锁,此时 A 请求缓过来了,就会 DEL 掉 B 请求创建的锁,此问题远比想象的要复杂,具体解决方案参见本文最后关于锁的若干个参考链接。
如此基本实现了单机锁,假如要实现分布锁,请参考:Distributed locks with Redis,不过分布式锁需要注意的地方更多:How to do distributed locking,Is Redlock safe。此外,还有中文版:基于Redis的分布式锁到底安全吗(上/下)。
https://huoding.com/2015/09/14/463hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io