【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();该语句是接着执行切点之后的逻辑,也就是创建优惠券。

相关推荐
oak隔壁找我8 小时前
JVM常用调优参数
java·后端
蝎子莱莱爱打怪12 小时前
OpenClaw 从零配置指南:接入飞书 + 常用命令 + 原理图解
java·后端·ai编程
回家路上绕了弯13 小时前
深入解析Agent Subagent架构:原理、协同逻辑与实战落地指南
分布式·后端
狼爷13 小时前
Go 没有 override?别硬套继承!用接口+嵌入,写更清爽的“覆盖”逻辑
java·go
小兔崽子去哪了16 小时前
Java 自动化部署
java·后端
ma_king16 小时前
入门 java 和 数据库
java·数据库·后端
后端AI实验室16 小时前
我用Cursor开发了3个月,整理出这套提效4倍的工作流
java·ai
码路飞20 小时前
GPT-5.3 Instant 终于学会好好说话了,顺手对比了下同天发布的 Gemini 3.1 Flash-Lite
java·javascript
SimonKing21 小时前
OpenCode AI编程助手如何添加Skills,优化项目!
java·后端·程序员
Seven971 天前
剑指offer-80、⼆叉树中和为某⼀值的路径(二)
java