Redis分布式锁

redis分布式锁应用场景:秒杀、大促之类的活动,在并发情况下对同一资源的访问

redis实现分布式锁:

    @Autowired
    @Qualifier("redisTemplate")
    private RedisTemplate<String, Object> redisTemplate;

    public Boolean redisLock() throws Exception {
        //生成分布式锁redis key
        String key = "REDIS_KEY";
        //生成分布式锁redis value
        String value = Thread.currentThread().getId() + ":" + UUID.randomUUID();
        try {
            logger.info("分布式锁key:" + key + ";分布式锁value:" + value);
            //加锁
            Boolean flag = redisTemplate.opsForValue().setIfAbsent(key, value, 60, TimeUnit.SECONDS);
            logger.info("添加分布式锁结果:" + flag);
            if (!flag) {
                throw new Exception("当前操作已有用户在处理,请稍后再试");
            }
            //业务逻辑

        } catch (Exception e) {
            logger.info(e.getMessage(), e);
            throw new Exception(e.getMessage());
        } finally {
            logger.info("删除分布式锁处理开始");
            //执行完方法后,删除分布式锁
            //校验是否是同一线程加的锁 只有同一线程加的锁才能去释放锁
            if(value.equals(redisTemplate.opsForValue().get(key))) {
                Boolean flag = redisLockUtils.unLock(key, value);
                logger.info("删除分布式锁结果:" + flag);
            }
        }
        return true;
    }

上面通过redis实现的分布式锁  针对一般的业务是可用的 但是还是会存在一个问题 由于我们考虑到锁的超时时间需要根据业务情况来定 不能设置太长 也不能设置太短  在这种情况下 可能会在某一时间方法执行的时间很长 或者jvm在进行垃圾回收(并行算法时回收期间会暂停程序的执行) 获取锁的线程业务还没执行完就释放了锁 导致其他线程获取锁成功  针对上面的情况 我们可以使用redisson进行分布式锁的实现 

redisson实现分布式锁:

添加依赖:

<dependency>
   <groupId>org.redisson</groupId>
   <artifactId>redisson</artifactId>
   <version>3.6.5</version>
</dependency>
   public Boolean redisLock() throws Exception {
        //生成分布式锁redis key
        String key = "REDIS_KEY";
        RLock redissonLock = redissonClient.getLock(key);
        try {
            //加锁
            redissonLock.lock();
            //业务逻辑

        } catch (Exception e) {
            logger.info(e.getMessage(), e);
            throw new Exception(e.getMessage());
        } finally {
            logger.info("删除分布式锁处理开始");
            redissonLock.unlock();
        }
        return true;
    }

通过redisson实现分布式锁 在并发情况下 只有第一个线程才能执行 redissonLock.lock(); 加锁成功。底层相当于执行了setIfAbsent(key, value, 30, TimeUnit.SECONDS)这个命令。   redissonLock.lock()默认超时时间30秒,这行代码在后台会开启一个定时续命的分线程,每隔一段时间(设置的超过时间的三分之一。 默认30秒超时 那么每隔10秒)检查当前线程是否还持有锁,如果持有则延长锁的时间,而其他线程会阻塞在redissonLock.lock()这行代码,通过while循环尝试加锁

redisson实现分布式锁原理图:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值