Redis 分布式锁:
- 1.互斥性:在任意时刻,只有一个用户获取锁
- 2.不会发生死锁。即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁。
- 3.具有容错性。只要大部分的Redis节点正常运行,客户端就可以加锁和解锁。
- 4.解铃还须系铃人。加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给解了。
下面方法:只满足-1、2、4 条件,单点Redis
? 我们的加锁代码满足我们可靠性里描述的三个条件。首先,set()加入了NX参数,可以保证如果已有key存在,则函数不会调用成功,也就是只有一个客户端能持有锁,满足互斥性。其次,由于我们对锁设置了过期时间,即使锁的持有者后续发生崩溃而没有解锁,锁也会因为到了过期时间而自动解锁(即key被删除),不会发生死锁。最后,因为我们将value赋值为requestId,代表加锁的客户端请求标识,那么在客户端在解锁的时候就可以进行校验是否是同一个客户端。由于我们只考虑Redis单机部署的场景,所以容错性我们暂不考虑。(多结点Redis模式下,存在数据同步延迟问题,导致用户判断lockKey是否存在不准确。)
public boolean tryGetRedisLock(Jedis jedis,String lockKey,String requestId,int expireTime){
String result = jedis.set(lockKey,requestId,SET_IF_NOT_EXIST,SET_WITH_EXPIRE_TIME,expireTime);
if("ok".equals(result)){
return true;
}
return false;
}
jedis.set()
- 第一个参数:锁的key值
- 第二个参数:锁的value值----解铃还须系铃人 A操作过慢,超时自动解锁,B获取锁,A操作完取解锁。设置标识,防止A把B的锁解开。
- 第三个参数:存在锁key,不执行此方法。判断是否已经有锁了
- 第四个参数:表示 开始 超时过期 功能–时间看第五个参数
- 第五个参数:超时时间
注意:reids 加锁 和 设置超时 一定要是原子操作
官方框架Redisson---->实现分布式锁:多个续约功能。续超时时间
分布式锁一般有三种实现方式:1. 数据库乐观锁;2. 基于Redis的分布式锁;3. 基于ZooKeeper的分布式锁。
|