• 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代码会最终执行!

  • 相关阅读:
    Exp9 Web安全基础
    EXP8 Web基础
    Exp7 网络欺诈防范
    Exp6 信息搜集与漏洞扫描
    Exp5 MSF基础应用
    Exp4 恶意代码分析
    Exp3 免杀原理与实践
    Exp2 后门原理与实践 20154317
    正则表达Regex替换标签
    正则表达式
  • 原文地址:https://www.cnblogs.com/zhangfengshi/p/14365937.html
Copyright © 2020-2023  润新知