分布式常见面试题:如何解决分布式锁的死锁问题

Java面试 潘老师 4周前 (06-17) 34 ℃ (0) 扫码查看

在日常开发中,像常见的秒杀扣库存这种需要访问同一资源的情况,并发读写时如果没有任何防护,很容易出现数据错乱的问题,比如超卖,库里的数据可能会出现负数。为解决此问题,我们引入了分布式锁,通常通过 Redis 来实现。它能让同一时刻只允许一个线程访问资源,超卖问题也就迎刃而解。

然而,分布式锁又带来了不少新麻烦,比如死锁问题,这出现的频率还挺高。常见场景有:加锁后没有程序去释放锁,一直被占用就产生了死锁;虽然写了释放锁的程序,但加锁后程序挂了,也会产生死锁;还有加锁时的原子性问题,没加上过期时间,程序一挂同样产生死锁等等。总的来说,死锁大多是因为加了锁却没释放,导致其他线程拿不到锁,造成大面积请求失败。

所以,解决问题的关键在于保障分布式锁能够正常释放。释放锁主要有两种方式,一是直接删掉锁的 key,二是设置过期时间。删掉锁的 key 时要注意,首先得判断锁是否被占用,占用了才执行删除操作,还要判断是否是当前线程加的锁,不能误删别的线程加的锁,同时要保证操作的原子性,这可以通过 lua 脚本来实现。设置过期时间的话,大家应该都不陌生,一般先 set nx,然后设置过期时间,到期就直接释放。不过这个步骤不是原子性的,好在从 Redis 2.6 开始,引入了新的 set 命令,可以直接设置锁的同时设置过期时间,方便了许多,或者也可以通过 lua 脚本来执行 set 和 expire 操作。

好了,以上就是关于分布式锁死锁问题的相关内容。


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/javainterview/13091.html
喜欢 (1)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】