SpringBoot 接口幂等性设计——防重复提交终极方案

📅 2026/7/9 1:30:43 👁️ 阅读次数 📝 编程学习
SpringBoot 接口幂等性设计——防重复提交终极方案

幂等性是指同一操作多次执行和一次执行的结果相同。支付、下单、转账等接口必须保证幂等性,否则用户多次点击就会产生多笔订单。

一、什么是幂等

非幂等:每次执行都会改变状态 请求1:扣款100元 → 余额900 请求2:扣款100元 → 余额800 ❌(重复扣款) 幂等:多次执行结果与一次相同 请求1:取消订单 → 订单已取消 请求2:取消订单 → 订单已取消 ✅(状态不变)

二、实现方案

1. 数据库唯一索引

// 订单表增加 order_no 唯一索引// 重复插入时数据库报错,捕获后返回"订单已存在"@TransactionalpublicOrdercreateOrder(OrderDTOdto){Orderorder=newOrder();order.setOrderNo(OrderNoGenerator.generate());// ...try{orderMapper.insert(order);returnorder;}catch(DuplicateKeyExceptione){thrownewBusinessException(400,"订单已存在,请勿重复提交");}}

2. Token + Redis(推荐)

@RestController@RequestMapping("/api")publicclassIdempotentController{@AutowiredprivateStringRedisTemplateredisTemplate;@GetMapping("/token")publicResultVO<String>getToken(){Stringtoken=IdUtil.simpleUUID();redisTemplate.opsForValue().set("idempotent:"+token,"1",30,TimeUnit.MINUTES);returnResultVO.success(token);}@PostMapping("/order")publicResultVO<?>createOrder(@RequestBodyOrderDTOdto,@RequestHeader("idempotent-token")Stringtoken){// 删除 Token,删除成功说明是首次请求Booleandeleted=redisTemplate.delete("idempotent:"+token);if(Boolean.FALSE.equals(deleted)){returnResultVO.error(400,"请勿重复提交");}// 业务逻辑...returnResultVO.success("下单成功");}}

前端流程:

1. 进入下单页 → 请求 /api/token 获取 Token 2. 提交订单 → header 携带 Token 3. 服务端校验 Token 是否存在,存在则删除并执行业务 4. 重复提交 → Token 已不存在 → 拒绝

💡 觉得有用的话,点赞 + 关注【张老师技术栈】吧!每周更新 Java/Python/爬虫 实战干货,不让你白来。