分布式红锁的加锁的lua底层设计原理

分布式红锁的加锁的lua底层设计原理

提前做2个动作:
1.先把3台 redis key全部清空(为了不受debug干扰,必须先删除锁)
127.0.0.1:6379> flushdb
OK

2.isLock = redLock.tryLock(1000530, 1000605*30, TimeUnit.MILLISECONDS);

debug的断点 断在 RedissonLock.tryLockInnerAsync(long leaseTime, TimeUnit unit, long threadId, RedisStrictCommand command)

<T> RFuture<T> tryLockInnerAsync(long leaseTime, TimeUnit unit, long threadId, RedisStrictCommand<T> command) {
    internalLockLeaseTime = unit.toMillis(leaseTime);

    return commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, command,
              "if (redis.call('exists', KEYS[1]) == 0) then " + //key不存在,说明前面没人拿到锁,太幸运了
                  "redis.call('hset', KEYS[1], ARGV[2], 1); " + //执行hset MY_REDLOCK UUID+threadId 1 的命令
                  "redis.call('pexpire', KEYS[1], ARGV[1]); " + //执行pexpire MY_REDLOCK设置锁的租约时间即过期时间。
                  "return nil; " +                              //返回nil,代表我已经拿到锁了
              "end; " +
              
              "if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " +//判断是不是我自己拿到了锁
                  "redis.call('hincrby', KEYS[1], ARGV[2], 1); " +       //如果是我自己就能进来,为我自己加1
                  "redis.call('pexpire', KEYS[1], ARGV[1]); " +          //再重新设置过期时间
                  "return nil; " +                                       //返回nil,代表我已经拿到锁了
              "end; " +
              //为以上if这段代码,提出2个疑问?
              //1.为什么是我自己(UUID+threadId,hash存在)就能进去?因为我上次已经拿到了锁,所以我就能进来,即重入锁,故红锁也是一个重入锁。
              //2.为什么我进去后,要给自己加1?这就是重入锁的原理了,要记录锁重入的次数,然后再次return nil,代表再次拿到锁。
              
              //返回key的剩余过期时间,前面2个if都是返回nil代表拿锁成功,这里返回剩余过期时间代表了锁已经被别人拿走,
              //为什么要给剩余时间?就是告诉你锁已经在别人那里了,你按我的是个时间在等待吧
              "return redis.call('pttl', KEYS[1]);",
                Collections.<Object>singletonList(getName()), internalLockLeaseTime, getLockName(threadId));
}

KEYS[1]:Collections.singletonList(getName()),为分布式锁的key,即MY_REDLOCK
ARGV[1]:internalLockLeaseTime 为锁的租约时间,即过期时间
ARGV[2]:getLockName(threadId)(4218379f-849d-498f-8c28-56f3fce42f71:52)代表了redis连接id+线程id,
即UUID+threadId,组成锁的获取者,就是谁拿到了该锁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值