超级悠悠
高性能程序定制、UI定制
576867

访问

1

评论

19

动态

2059

运行

来过
设计群: 70888820
位置: luzhou·sichuan

- 今日签到 -

今日暂无签到

首页破碎代码SpringBoot3使用注解实现Redis分布式锁(解决幂等性问题)

SpringBoot3使用注解实现Redis分布式锁(解决幂等性问题)

评论 0/访问 2037/分类: 破碎代码/发布时间:

pom.xml

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.6.5</version>
</dependency>

HasRedissonLock.java

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface HasRedissonLock {
    /**
     * 锁的Key
     */
    String value();
    /**
     * 锁的过期时间
     */
    int leaseTime() default 10;
}

RedissonLock.java

@Aspect
@Component
public class RedissonLock {
    @Autowired
    private RedissonClient redissonClient;
    /**
     * Aop切面方法
     *
     * @param joinPoint 切点
     */
    @Around("execution(public * *(..)) && @annotation(com.app.aop.has.HasRedissonLock)")
    public Object interceptor(ProceedingJoinPoint joinPoint) throws Throwable {
        //获取登录用户ID
        Long loginUserId = TokenUtils.getRequestUserId();
        //Method
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        HasRedissonLock hasRedissonLock = method.getDeclaredAnnotation(HasRedissonLock.class);
        //获取锁的Key
        String lockKey = hasRedissonLock.value() + ":" + loginUserId;
        //获取锁的过期时间
        long leaseTime = hasRedissonLock.leaseTime();
        //获取分布式锁对象
        RLock lock = redissonClient.getLock(lockKey);
        //尝试获取锁
        boolean isLocked = false;
        try {
            isLocked = lock.tryLock(leaseTime, TimeUnit.SECONDS);
            if (!isLocked) throw new BusinessException("请勿重复请求");
            //执行目标方法
            return joinPoint.proceed();
        } finally {
            //释放锁
            if (isLocked) lock.unlock();
        }
    }
}

接口使用

@HasRedissonLock("save_article")
@PostMapping("/save")
public R<?> save(@RequestBody ArticleBo bo) {
    articleService.save(bo);
    return R.ok(null, "添加成功");
}

收藏

点赞

打赏