请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

Redis分布式锁过期时间的疑问

视频中分布式锁lock函数的上锁逻辑是如果发现key过期,则先做一次get再做一次getandset,然后比较两个的返回值一不一样来判断是否取到锁。如果两个线程竞争,两个线程都会调用getandset,那对于没取到锁的线程依然会调用了getandset,那redis里面的值不就被改变了吗(如果被改变,那获得锁的线程在解锁时不就也会失败吗),请问这里怎么保证取锁失败的线程,在调用getandset后不会影响程序的正常进行?

正在回答 回答被采纳积分+3

3回答

慕尼黑5723975 2022-04-11 18:52:15

是的,这块有bug,就是第二个线程只要跟第一个线程的毫秒不完全一样,那么第二个线程在执行getandset以后会导致解锁失败,从而造成死锁,很明显了已经。

1 回复 有任何疑惑可以回复我~
心死则忙 2021-08-02 09:14:58

同样的疑问,这块逻辑有问题!第二个线程getAndSet()之后虽然会加锁失败,但是会改变当前的value,导致第一个线程无法解锁!

0 回复 有任何疑惑可以回复我~
  • 提问者 慕娘83406391 #1
    而且这里其实还有一个问题,假如我有三个线程A,B,C同时发现了过期并尝试竞争锁,第一个A获得了锁并且更新redis中的值为a,第二个B发现旧的值不等于新的值,但是也更新redis中的值,此时为b,B更新完了以后C才做get + getset的操作,C会发现get取到的是b并且getset也取到的是b,他就认为自己拿到锁了,那这样其实A拿到了锁在扣库存,C也拿到了锁在扣库存,这不会超卖吗
    回复 有任何疑惑可以回复我~ 2021-08-03 13:30:28
  • 心死则忙 回复 提问者 慕娘83406391 #2
    好久没登陆了。刚看了下你的逻辑,确实也会发生超卖的问题。廖师兄这块逻辑本身就不对,说句题外话,这门课和微服务没任何关系,不知道为啥题目有个微服务
    回复 有任何疑惑可以回复我~ 2021-08-22 21:31:45
廖师兄 2021-07-26 11:13:45
  1. 你的意思就是,一个currenttime只有一个线程操作吧,那样效率太低了。

  2. 不太明白你的意思。你可否用实例代码来说明

0 回复 有任何疑惑可以回复我~
  • 提问者 慕娘83406391 #1
    public boolean lock(String key, String value) {
            if(redisTemplate.opsForValue().setIfAbsent(key, value)) {
                return true;
            }
            //currentValue=A   这两个线程的value都是B  其中一个线程拿到锁
            String currentValue = redisTemplate.opsForValue().get(key);
            //如果锁过期
            if (!StringUtils.isEmpty(currentValue)
                    && Long.parseLong(currentValue) < System.currentTimeMillis()) {
                //获取上一个锁的时间
                String oldValue = redisTemplate.opsForValue().getAndSet(key, value);   // 这里!!!!!!!
                if (!StringUtils.isEmpty(oldValue) && oldValue.equals(currentValue)) {
                    return true;
                }
            }
    
            return false;
        }
    
    currenttime那个是我理解有问题。咱们只讨论另一个问题,我现在想知道A,B两个线程,他们都同时发现之前的锁过期了,于是开始竞争锁,那他们无论谁获取到锁,都会调用getandset,只不过没有取到锁的线程这个函数会返回false,但是它依然掉用了getandset,就也改变了redis的值,那对于竞争到锁的线程,在解锁时会发现value和自己设置的不一样,就无法正常解锁,这个问题可以帮我解答一下吗
    回复 有任何疑惑可以回复我~ 2021-07-26 11:30:06
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信