java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot接口幂等性

SpringBoot接口幂等性的实现方案

作者:张老师技术栈

幂等性是指同一操作多次执行和一次执行的结果相同,支付、下单、转账等接口必须保证幂等性,否则用户多次点击就会产生多笔订单,本文给大家介绍了SpringBoot接口幂等性的实现方案,需要的朋友可以参考下

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

一、什么是幂等

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

二、实现方案

1. 数据库唯一索引

// 订单表增加 order_no 唯一索引
// 重复插入时数据库报错,捕获后返回"订单已存在"
@Transactional
public Order createOrder(OrderDTO dto) {
    Order order = new Order();
    order.setOrderNo(OrderNoGenerator.generate());
    // ...
    try {
        orderMapper.insert(order);
        return order;
    } catch (DuplicateKeyException e) {
        throw new BusinessException(400, "订单已存在,请勿重复提交");
    }
}

2. Token + Redis(推荐)

@RestController
@RequestMapping("/api")
public class IdempotentController {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @GetMapping("/token")
    public ResultVO<String> getToken() {
        String token = IdUtil.simpleUUID();
        redisTemplate.opsForValue()
            .set("idempotent:" + token, "1", 30, TimeUnit.MINUTES);
        return ResultVO.success(token);
    }

    @PostMapping("/order")
    public ResultVO<?> createOrder(@RequestBody OrderDTO dto,
                                    @RequestHeader("idempotent-token") String token) {
        // 删除 Token,删除成功说明是首次请求
        Boolean deleted = redisTemplate.delete("idempotent:" + token);
        if (Boolean.FALSE.equals(deleted)) {
            return ResultVO.error(400, "请勿重复提交");
        }
        // 业务逻辑...
        return ResultVO.success("下单成功");
    }
}

前端流程:

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

到此这篇关于SpringBoot接口幂等性的实现方案的文章就介绍到这了,更多相关SpringBoot接口幂等性内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文