防重复提交:Redis 注解 AOP 组件设计
文章目录
为什么要做成组件
重复提交如果每个接口都手写一遍,代码会很快变乱。更好的方式是把它收进一个注解组件里,让业务方只关心"这个接口要不要防重",而不是每次都重复写 Redis 判断逻辑。
组件结构
一个完整的设计通常包括:
- 注解:声明哪些接口需要防重
- 切面:在方法执行前拦截
- Key 生成器:决定幂等 key 怎么拼
- Redis 访问层:做占位、过期、释放
- 返回包装:重复请求时直接返回统一结果
一个常见注解
java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NoRepeatSubmit {
String key() default "";
long expireSeconds() default 30;
}
切面怎么做
核心就两步:先拿到 key,再尝试写入 Redis。如果写不进去,说明这次请求已经在处理中,直接返回。
java
boolean locked = redisTemplate.opsForValue()
.setIfAbsent(redisKey, "1", expireSeconds, TimeUnit.SECONDS);
设计时别踩的坑
- key 不能只用接口名,不然同一个接口不同用户会互相影响
- 过期时间不能太短,不然请求还没结束锁就没了
- 不要把这个组件当分布式锁用,它更像一次性幂等票据
- 业务成功后最好记录结果,重复请求可以直接返回上一次结果
组件目标
它的目标不是"绝对禁止所有重复",而是把大部分重复请求挡在入口,把并发冲突变成可控问题。