• redis如何避免释放锁时把别人的锁释放掉


    场景:
    假如线程A获取分布式锁进入方法A,由于某种原因Hang住了 到了指定时间释放锁,这个时候线程B进入得到锁,这个时候线程B很顺利完成业务逻辑操作,然后释放掉锁,就在这个时候线程A开始继续往下执行代码,按照这个逻辑他最终会执行finally代码块 执行到释放锁的逻辑
    那么这个时候如果锁的值一样,很有可能会释放掉已经获取锁的线程持有的那把锁。
    那么该如何设计呢?
    答案很简单,可以把锁的值设为UUID,保证唯一,这样每个线程的锁的值都是不一样的!

    我们释放REDIS的锁 是通过执行LUA脚本实现的
    if redis.call('get', KEYS[1]) == ARGV[1] then
        return redis.call('del', KEYS[1])
    else
        return 0
    end
    

      



    调用的时候,锁的值是UUID的值。那为什么要设计为UUID的值,而不是随便来一个值呢?
    String lockVal = UUID.randomUUID().toString();

    public
    boolean unlock(String lockName, String lockVal) { log.info("释放redis锁 {}", lockVal); Object eval = redisTemplate.execute(unlockLuaScript, Lists.newArrayList(lockName), lockVal); if (eval != null) { ArrayList<Long> evalArr = (ArrayList<Long>) eval; boolean b = evalArr.get(0) == 1; if (b) { log.info("释放redis锁成功 {}", lockVal); return true; } } log.error("释放redis锁超时 {}", lockVal); return false; }

    上面这段代码解释了为什么redis锁的值要设计成为UUID的uuid形式  因为假如redis业务逻辑时间执行的比较长,可能导致超时释放锁,那么另一线程获取锁,其执行完相关业务代码后,释放了锁。然后上一个线程执行完逻辑后,继续执行 (这个时候它是无锁的状态)但还是会去释放锁因为finally代码会最终执行!

  • 相关阅读:
    Python学习之路 (五)爬虫(四)正则表示式爬去名言网
    Python学习之路 (四)爬虫(三)HTTP和HTTPS
    Python学习之路 (三)爬虫(二)
    Python学习之路 (二)爬虫(一)
    Python学习之路 (一)开发环境搭建
    ZooKeeper学习之路 (十一)ZooKeeper API的应用
    ZooKeeper学习之路 (十)Hadoop的HA集群的机架感知
    Spring Security
    Spring Validation
    [转]linux下完全备份数据库mysql
  • 原文地址:https://www.cnblogs.com/zhangfengshi/p/14365937.html
Copyright © 2020-2023  润新知