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

原文地址:https://www.cnblogs.com/zhangfengshi/p/14365937.html