第一版
基于redis 实现的分布式锁
实现逻辑和基本原理
逻辑:
1、每一次访问进来都先去获得redis 锁 如果获得到 则继续执行,如果获取不到 则直接返回
2、redis 的key 设有过期时间 避免某个请求处理不当(或方法执行到一半宕机或网络原因)导致 redis key 不能正确释放 死锁
3 在 finally 方法里进行手工释放锁
基本原理(即有什么样的理论基础 才可以用redis做分布式锁):
1、setIfAbsent 即 setnx 当key不存在时设置成功,当key 存在时会设置失败
2、redis设置key 和 设置过期时间 必须为原子性
否则在设置完key 后系统宕机 此时还没来得及设置过期时间 那么这个可以就成了永久的key了 就会产生死锁的情况
setIfAbsent 不是原子性的 (稍后讲解决方案)
问题
1、当这个方法执行时间大于10秒 此时 方法还没有执行完 key就自动过期了 此时 第二个请求就可以进来了 ,实际上是不应该进来的。
2、接 第一条 如果第二条请求还没执行完 第一条请求执行完了并释放了锁 ,此时第三条请求可以顺利进来 ,如此循环 这个锁就失效了。

第二方案:
基于redis 实现的分布式锁
解决上述第二个问题:
1、为每个请求生成一个uuid
2、如果第二条请求还没执行完 第一条请求执行完了 然后进行判断 如果当前锁是自己的进行释放,如果当前锁不是自己的就不释放,这样就 避免了锁失效。

第一个问题暂时还没解决*********************************

对于 setIfAbsent 不是原子性的问题 可以使用lua 脚本去实现。

相关文章: