7.3-基于Redis实现分布式锁的几种坑你是否踩过《下》—小滴课堂学习笔记


7.3-基于Redis实现分布式锁的几种坑你是否踩过《下》


基于Redis实现分布式锁的几种坑你是否踩过《下》

简介:手把手教你彻底掌握分布式锁+原生代码编写

存在什么问题?

多个命令之间不是原子性操作,如setnx和expire之间,如果setnx成功,但是expire失败,且宕机了,则这个资源就是死锁

使用原子命令:设置和配置过期时间  setnx / setex

如: set key 1 ex 30 nx

java里面 redisTemplate.opsForValue().setIfAbsent("seckill_1","success",30,TimeUnit.MILLISECONDS)


业务超时,存在其他线程勿删,key 30秒过期,假如线程A执行很慢超过30秒,则key就被释放了,其他线程B就得到了锁,这个时候线程A执行完成,而B还没执行完成,结果就是线程A删除了线程B加的锁

可以在 del 释放锁之前做一个判断,验证当前的锁是不是自己加的锁, 那 value 应该是存当前线程的标识或者uuid

String key = "coupon_66"

String value = Thread.currentThread().getId()

if(setnx(key,value) == 1){

   expire(key,30,TimeUnit.MILLISECONDS)

   try {

       //做对应的业务逻辑

   } finally {

  //删除锁,判断是否是当前线程加的

  if(get(key).equals(value)){

          //还存在时间间隔

          del(key)

       }

   }

}else{


  //睡眠100毫秒,然后自旋调用本方法

}

进一步细化误删

当线程A获取到正常值时,返回带代码中判断期间锁过期了,线程B刚好重新设置了新值,线程A那边有判断value是自己的标识,然后调用del方法,结果就是删除了新设置的线程B的值

核心还是判断和删除命令 不是原子性操作导致

总结

加锁+配置过期时间:保证原子性操作

解锁: 防止误删除、也要保证原子性操作


那如何解决呢?下集讲解


《小滴课堂-Redis6学习笔记》

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容