Java 生产环境接口防重提交实战方案
目录一、核心方案选型(生产首选)二、实战实现(完整可复制)1. 依赖(Maven)2. 定义防重提交注解(核心)3. 防重 Key 生成策略(生产级)4. AOP 切面实现(核心防重逻辑)5. 接口使用(超级简单)三、生产环境必须优化的 4 个关键点1. Key 必须包含用户标识2. 过期时间不能太长也不能太短3. 必须使用 setIfAbsent(原子操作)4. 接口必须保证幂等性四、高并发场景进阶方案(生产必看)方案 1:请求参数签名(更精准)方案 2:Redisson 可重入锁(更稳定)方案 3:全局异常统一返回五、前端辅助防重(必须做)六、最终生产防护体系(三层加固)七、常见坑点(避坑指南)总结生产环境接口重复提交(用户连续点击、网络重试、接口重试)会导致:重复下单、重复扣款、重复创建数据、数据错乱等严重问题。本文给你一套企业级、可直接落地、生产可用的防重提交实战方案,包含:原理 + 代码 + 配置 + 坑点。一、核心方案选型(生产首选)方案适用场景生产推荐度Redis + 分布式锁微服务、集群、高并发⭐⭐⭐⭐⭐ 首选数据库唯一索引强一致性、幂等兜底⭐⭐⭐⭐ 必须配合前端按钮禁用基础防护⭐⭐ 辅助最终实战方案:前端防点 + Redis 分布式锁防重 + 数据库唯一索引兜底二、实战实现(完整可复制)1. 依赖(Maven)!-- Redis -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId /dependency !-- AOP -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-aop/artifactId /dependency2. 定义防重提交注解(核心)import java.lang.annotation.*; import java.util.concurrent.TimeUnit; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface RepeatSubmit { /** * 防重时间窗口(默认 2 秒) */ int expire() default 2; /** * 时间单位 */ TimeUnit timeUnit() default TimeUnit.SECONDS; /** * 提示信息 */ String message() default "操作过于频繁,请稍后再试"; }3. 防重 Key 生成策略(生产级)Key 必须唯一,推荐组合:prefix:用户唯一标识:接口URI:请求参数签名import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; public class RequestKeyGenerator { // 从请求头拿 token(你项目里的用户标识) public static String getUserId() { HttpServletRequest request = getRequest(); // 替换成你项目的用户ID获取方式 return request.getHeader("userId"); } public static HttpServletRequest getRequest() { RequestAttributes attributes = RequestContextHolder.getRequestAttributes(); return ((ServletRequestAttributes) attributes).getRequest();