【CouponHub开发记录】SpringAop和分布式锁进行自定义注解实现防止重复提交

当我们创建优惠券时,可能会出现由于网络延时等问题导致用户重复点击创建优惠券模板的操作。我们可以通过分布式锁,给当前线程进行加锁。如果获取锁失败说明重复提交。

直接再创建优惠券之前进行加锁。

但是这样直接写到业务当中导致代码比较繁琐,冗余。因此我们可以创建自定义注解,将该逻辑抽离出来。

首先定义一个注解

java 复制代码
/**
 * 防止用户重复提交表单信息切面控制器
 * <p>
 * 作者:马丁
 * 加项目群:早加入就是优势!500人内部项目群,分享的知识总有你需要的 <a href="https://t.zsxq.com/cw7b9" />
 * 开发时间:2024-07-10
 */
@Aspect
@RequiredArgsConstructor
public final class NoDuplicateSubmitAspect {

    private final RedissonClient redissonClient;

    /**
     * 增强方法标记 {@link NoDuplicateSubmit} 注解逻辑
     */
    @Around("@annotation(com.nageoffer.onecoupon.framework.idempotent.NoDuplicateSubmit)")
    public Object noDuplicateSubmit(ProceedingJoinPoint joinPoint) throws Throwable {
        NoDuplicateSubmit noDuplicateSubmit = getNoDuplicateSubmitAnnotation(joinPoint);
        // 获取分布式锁标识
        String lockKey = String.format("no-duplicate-submit:path:%s:currentUserId:%s:md5:%s", getServletPath(), getCurrentUserId(), calcArgsMD5(joinPoint));
        RLock lock = redissonClient.getLock(lockKey);
        // 尝试获取锁,获取锁失败就意味着已经重复提交,直接抛出异常
        if (!lock.tryLock()) {
            throw new ClientException(noDuplicateSubmit.message());
        }
        Object result;
        try {
            // 执行标记了防重复提交注解的方法原逻辑
            result = joinPoint.proceed();
        } finally {
            lock.unlock();
        }
        return result;
    }

接着定义一个切面

其中

该环绕通知会拦截所有带这个注解的方法

接着去执行获取分布式锁、然后执行相应逻辑

result = joinPoint.proceed();该语句是接着执行切点之后的逻辑,也就是创建优惠券。

相关推荐
栈溢出了34 分钟前
Redis 分片集群与哈希槽笔记
java·redis·笔记·spring
遨游DATA42 分钟前
Spring Boot 启动失败排查:如何区分多 Bean 冲突与清理阶段异常
java·spring boot·后端
wabs6661 小时前
关于单调栈【力扣739.每日温度的思考】
java·开发语言
雪碧聊技术2 小时前
为什么要学函数式编程?
java·函数式编程
aaPIXa6222 小时前
C++ 用 13 条规则让模型写出安全现代 C++
java·c++·安全
2601_949817723 小时前
C++指针与引用深度精讲:底层原理、差异对比与高阶实战陷阱
java·jvm·c++
va学弟4 小时前
Java 网络通信编程(10):Channel 和 Selector
java·开发语言
小张小张爱学习4 小时前
Apache Dubbo 3 + Spring Boot 3 多模块 Maven 项目,演示基于 Zookeeper 注册中心的 RPC 调用
java·dubbo
阿pin5 小时前
Java随笔-ConcurrentHashMap
java·开发语言·哈希算法
长不胖的路人甲5 小时前
RabbitMQ 死信队列 DLQ
分布式·rabbitmq