加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

Redis实现漫衍式锁的正确姿势

发布时间:2019-01-26 11:38:29 所属栏目:编程 来源:编辑之路
导读:一、媒介 在我们一般事变中,除了Spring和Mybatis外,用到最多无外乎漫衍式缓存框架Redis。可是许多事变许多年的伴侣对Redis还处于一个最基本的行使和熟悉。以是我就像把本身对漫衍式缓存的一些领略和应用清算一个系列,但愿可以辅佐到各人加深对Redis的理

2. 当锁逾期的时辰,假如多个客户端同时执行jedis.getSet()要领,固然最终只有一个客户端加锁,可是这个客户端的锁的逾期时刻也许被其他客户端包围。不具备加锁息争锁必需是统一个客户端的特征。办理上面这段代码的方法就是为每个客户端加锁添加一个独一标示,已确保加锁息争锁操纵是来自统一个客户端。

3.2 解锁错误姿势

漫衍式锁的实现无法就2个要领,一个加锁,一个就是解锁。下面我们来看下解锁的错误姿势。

错误姿势1.

  1. /** 
  2.      * 解锁错误姿势1 
  3.      * @param jedis 
  4.      * @param lockKey 
  5.      */ 
  6.     public static void wrongReleaseLock1(Jedis jedis, String lockKey) { 
  7.         jedis.del(lockKey); 
  8.     } 

上面实现是最简朴直接的解锁方法,这种不先判定拥有者而直接解锁的方法,会导致任何客户端都可以随时解锁。纵然这把锁不是它上锁的。

错误姿势2:

  1. /** 
  2.      * 解锁错误姿势2 
  3.      * @param jedis 
  4.      * @param lockKey 
  5.      * @param requestId 
  6.      */ 
  7.     public static void wrongReleaseLock2(Jedis jedis, String lockKey, String requestId) { 
  8.  
  9.         // 判定加锁与解锁是不是统一个客户端 
  10.         if (requestId.equals(jedis.get(lockKey))) { 
  11.             // 若在此时,这把锁溘然不是这个客户端的,则会误解锁 
  12.             jedis.del(lockKey); 
  13.         } 

既然错误姿势1中没有判定锁的拥有者,那姿势2中判定了拥有者,那错误缘故起因又在那边呢?谜底又是原子性上面。由于判定和删除不是一个原子性操纵。在并发的时辰很也许产生扫除了此外客户端加的锁。详细场景有:客户端A加锁,一段时刻之后客户端A举办解锁操纵时,在执行jedis.del()之前,锁溘然逾期了,此时客户端B实行加锁乐成,然后客户端A再执行del要领,则客户端A将客户端B的锁给扫除了。从而不也不满意加锁息争锁必需是统一个客户端特征。办理思绪就是必要担保GET和DEL操纵在一个事宜中举办,担保其原子性。

四、Redis实现漫衍式锁的正确姿势

方才先容完了错误的姿势后,从上面错误姿势中,我们可以知道,要行使Redis实现漫衍式锁。加锁操纵的正确姿势为:

  1. 行使setnx呼吁担保互斥性
  2. 必要配置锁的逾期时刻,停止死锁
  3. setnx和配置逾期时刻必要保持原子性,停止在配置setnx乐成之后在配置逾期时刻客户端瓦解导致死锁
  4. 加锁的Value 值为一个独一标示。可以回收UUID作为独一标示。加锁乐成后必要把独一标示返回给客户端来用来客户端举办解锁操纵

解锁的正确姿势为:

1. 必要拿加锁乐成的独一标示要举办解锁,从而担保加锁息争锁的是统一个客户端

在此我向各人保举一个架构进修交换圈:830478757  辅佐打破瓶颈 晋升思想手段

2. 解锁操纵必要较量独一标示是否相称,相称再执行删除操纵。这2个操纵可以回收Lua剧本方法使2个呼吁的原子性。

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读