721547

访问

6

评论

14

动态

2216

运行天数

立即签到

保洁阿姨

拥有60+年的前端设计经验
接前后端定制
四川·泸州
2024-09-01 00:12:55来过

视频

Video

最新用户

User(20)

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

评论 0|访问 3705|分类: 破碎代码|发布时间: 2023-12-14 14:06:08

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, "添加成功");
}
评论互动
暂无数据