SpringBoot中使用注解来实现 Redis 分布式锁
发布日期:2021-04-30 21:12:18 浏览次数:87 分类:精选文章

本文共 3364 字,大约阅读时间需要 11 分钟。

Redis?????????????

??????????????????????????????????Redis????????????????????????????Redis??????????????????

????

??????????????????????????????????????????????????????????????????????????????????????????????

????????

?????????Redis????????????AOP?????????????????????????????

??????

  • ???????????RedisLockAnnotation???????????????????????????????????

  • AOP???????Spring?AOP?????????????????????

  • ??????????????????????????????????Redis?setIfAbsent???????

  • ????????????????????????????????????????????????????

  • ???????????????????????????????????

  • ????

    ????

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface RedisLockAnnotation {
    int lockField() default 0;
    int tryCount() default 3;
    RedisLockTypeEnum typeEnum();
    long lockTime() default 30;
    }

    ??????

    @Pointcut("cn.sevenyuan.demo.aop.lock.RedisLockAnnotation")
    public void redisLockPC() {}
    @Around("cn.sevenyuan.demo.aop.lock.RedisLockAnnotation")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
    Method method = pjp.resolveMethod();
    RedisLockAnnotation annotation = method.getAnnotation(RedisLockAnnotation.class);
    RedisLockTypeEnum typeEnum = annotation.typeEnum();
    Object[] params = pjp.getArgs();
    String ukString = params[annotation.lockField()].toString();
    String businessKey = typeEnum.getUniqueKey(ukString);
    String uniqueValue = UUID.randomUUID().toString();
    try {
    boolean isLock = redisTemplate.opsForValue().setIfAbsent(businessKey, uniqueValue);
    if (!isLock) {
    throw new Exception("?????");
    }
    redisTemplate.expire(businessKey, annotation.lockTime(), TimeUnit.SECONDS);
    holderList.add(new RedisLockDefinitionHolder(businessKey, annotation.lockTime(),
    System.currentTimeMillis(), Thread.currentThread(), annotation.tryCount()));
    return pjp.proceed();
    } catch (InterruptedException e) {
    log.error("?????");
    throw new Exception("?????");
    } catch (Exception e) {
    log.error("??????");
    throw e;
    } finally {
    redisTemplate.delete(businessKey);
    log.info("??????Key?" + businessKey);
    }
    return null;
    }

    ??????

    @Scheduled(fixedDelay = 2, initialDelay = 0)
    public void scheduleTask() {
    Iterator
    iterator = holderList.iterator();
    while (iterator.hasNext()) {
    RedisLockDefinitionHolder holder = iterator.next();
    if (holder == null) {
    iterator.remove();
    continue;
    }
    // ???????
    if (redisTemplate.opsForValue().get(holder.getBusinessKey()) == null) {
    iterator.remove();
    continue;
    }
    // ????????
    long currentTime = System.currentTimeMillis();
    boolean shouldExtend = (holder.getLastModifyTime() + holder.getModifyPeriod()) <= currentTime;
    if (shouldExtend) {
    holder.setLastModifyTime(currentTime);
    redisTemplate.expire(holder.getBusinessKey(), holder.getLockTime(), TimeUnit.SECONDS);
    holder.setCurrentCount(holder.getCurrentCount() + 1);
    log.info("???????Key?" + holder.getBusinessKey() + ", try count?" + holder.getCurrentCount());
    }
    }
    }

    ?????

    ???????????????????????????????????????????????????????????????????????????????????????????

    ?????????????????????????????????????????????????????

    上一篇:python入门必学:函数式编程20篇文章合集
    下一篇:【详细+超基础】Java-学习笔记 06

    发表评论

    最新留言

    很好
    [***.229.124.182]2026年06月24日 19时10分55秒