基于redis实现分布式锁

实现方式

分布式锁一般有三种实现方式:1、基于数据库的乐观锁;2、基于redis实现;3、基于zookeeper的分布式锁。本文内容主要基于redis实现分布式。

具备条件

确保锁可用,必须要满足一下几个条件:

1、互斥性,任意时刻只有一个用户能持有锁

2、不会产生死锁,假设某个用户在持有锁的期间由于服务崩溃或者其他原因没有主动释放锁,也能保证后续其他用户可以加锁

3、加锁和解锁必须是同一用户,B用户无法解除A用户加的锁

代码实现

1、引入Jedis组建依赖

2、加锁

这里使用key作为锁,value作为加锁的人的标识,用于后续的解锁。

(jedis的set方法中关于   NX | XX   的区别,NX是值不存在的时候才会把值成功设置进去,XX是只有值存在的时候才会把值成功设置进去)

错误的示范加锁情况一:

这里加锁和设置过期时间采用两条命令,不具备原子性,如果中途发生故障,会产生死锁。

错误的示范加锁情况二:

这种写法:第一比较麻烦;第二需要分布式部署的几台服务器的时间必须同步;第三无法保证解锁的是否和加锁的是同一个用户

3、解锁

这里使用  eval() 方法运行Lua脚本,首先获取锁对应的value值,检查是否与requestId相等,如果相等则删除锁(解锁)。

因为确保操作需要原子性,并且保证加锁和解锁的人是同一个,使用Lua脚本可以很方便的确保这两点。

解锁错误示范一:

问题:没有保证加锁人和解锁人是同一个

解锁错误示范二:

问题:多线程环境中,在获取锁之后,锁可能由于时间过期,自动释放,然后这个时候其他线程加了锁,就会导致锁的归属人发生了变化,这时候解的锁就是别人的锁。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值