这里省略了一些中间代码,这里主要看tryAcquire() 方法,这里传递的过期时间为-1,然后就是当前的线程id,接着就是核心的lua脚本执行流程,我们来一步步看看是如何执行的:
1"if (redis.call('exists', KEYS[1]) == 0) then " +2 "redis.call('hset', KEYS[1], ARGV[2], 1); " +
3 "redis.call('pexpire', KEYS[1], ARGV[1]); " +
4 "return nil; " +
5"end; " +
KEYS[1] 参数是:“anyLock”
ARGV[2] 是:“id + ":" + threadId”
首先用的exists 判断redis中是否存在当前key,如果不存在就等于0,然后执行hset指令,将“anyLock id:threadId 1”存储到redis中,最终redis存储的数据类似于:
1{2 "8743c9c0-0795-4907-87fd-6c719a6b4586:1":1
3}
偷偷说一句,最后面的一个1 是为了后面可重入做的计数统计,后面会有讲解到。
接着往下看,然后使用pexpire设置过期时间,默认使用internalLockLeaseTime为30s。最后返回为null,即时加锁成功。
Redisson 可重入原理我们看下锁key存在的情况下,同一个机器同一个线程如何加锁的?
1"if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " +2 "redis.call('hincrby', KEYS[1], ARGV[2], 1); " +
3 "redis.call('pexpire', KEYS[1], ARGV[1]); " +
4 "return nil; " +
5"end; " +
6"return redis.call('pttl', KEYS[1]);",