当前位置: 首页 > news >正文

幂等性介绍和下单接口幂等性保证实现方案

幂等性(Idempotence) 是一个数学和计算机科学中的核心概念,指一个操作或函数执行一次与重复多次的效果相同。以下是详细解析:


1. 数学定义

在数学中,幂等性指满足以下条件的运算:

  • 运算的重复不改变结果
    对于函数 ( f ),若 ( f(f(x)) = f(x) ),则 ( f ) 是幂等的。
    示例
    • 绝对值函数:( \text{abs}(\text{abs}(x)) = \text{abs}(x) )。
    • 集合运算:并集(( A \cup A = A ))、交集(( A \cap A = A ))。

2. 计算机科学中的应用

HTTP幂等性
  • 定义:客户端重复发送同一请求,服务器状态与单次执行一致。
  • 常见方法
    • 幂等方法:GET、PUT、DELETE(如删除同一资源多次结果相同)。
    • 非幂等方法:POST(如重复提交订单会创建多个资源)。
  • 设计原则
    • 通过**唯一标识符(如Token)**防止重复操作(如支付场景)。
    • 使用PUT替代POST进行更新(确保幂等)。
分布式系统
  • 消息队列:消费者需处理重复消息,确保幂等(如通过消息ID去重)。
  • 数据库操作
    • 使用条件更新(如 UPDATE ... WHERE version = 1)避免重复写入。
    • 利用唯一约束(如主键、唯一索引)防止重复插入。
函数式编程
  • 纯函数:无副作用的函数天然幂等(如 len("hello") 多次调用结果相同)。
  • 高阶函数:如 mapfilter 对同一输入重复应用结果不变。

3. 实际案例

  • 支付系统:用户重复点击支付按钮,系统通过订单号校验确保只扣款一次。
  • 缓存更新:设置缓存时,多次设置同一值不影响结果(如 SET key=value)。

4. 以下单接口为例说明如何设计幂等接口

在电商或支付系统中,下单接口的幂等性是核心要求之一,必须确保同一笔订单不会因为前端重试、网络重传或系统重试而被重复创建

以下是下单接口保证幂等性的完整实现方案,结合当前主流实践和最新资料:


✅ 4.1 核心目标

同一客户端多次提交同一笔订单,只创建一次订单记录,不重复扣库存、不重复支付。


✅ 4.2 实现方案(4种主流方式)
方案名称原理适用场景实现要点
唯一索引 + 幂等Key利用数据库唯一索引防止重复插入有明确业务唯一标识(如订单号、业务单号)幂等Key作为唯一索引字段,插入失败即说明已处理过
Token机制(推荐)每次下单前获取一次性Token,提交时携带,服务端校验并销毁前端表单提交、防重复点击Token存Redis,校验+删除需原子操作(Lua脚本)
状态机幂等利用订单状态控制流转,防止重复更新订单状态变更(如支付、取消)只有处于“待支付”状态才允许支付操作
分布式锁对同一用户或同一订单加锁,串行处理高并发、无唯一业务键场景使用Redis/ZK加锁,锁粒度需细(如userId+productId)

✅ 4.3 推荐组合实现(Token + 唯一索引)
✅ 流程图(简化版)
客户端进入下单页 → 请求 /order/token → 服务端生成Token并返回
客户端提交订单 → 携带Token + 订单数据
服务端:1. Lua脚本校验并删除Token(原子操作)2. 检查订单表是否已存在(幂等Key)3. 创建订单(事务中插入订单、库存扣减、防重记录)4. 返回结果
✅ 关键代码结构(Spring Boot + Redis)
// 1. 生成Token
@GetMapping("/order/token")
public String createToken() {String token = UUID.randomUUID().toString();redisTemplate.opsForValue().set("order:token:" + token, "1", Duration.ofMinutes(10));return token;
}// 2. 校验Token + 下单
@PostMapping("/order/create")
@Transactional
public void createOrder(@RequestBody CreateOrderRequest req) {String key = "order:token:" + req.getToken();// Lua脚本:存在则删除,返回1;不存在返回0Long result = (Long) redisTemplate.execute(luaScript, Collections.singletonList(key));if (result == null || result == 0) {throw new BizException("请勿重复提交订单");}// 幂等Key:userId + productId + skuId + 时间戳(或业务单号)String idempotentKey = buildIdempotentKey(req);try {orderMapper.insertSelective(req.toOrder(idempotentKey));} catch (DuplicateKeyException e) {log.warn("订单已存在,幂等Key:{}", idempotentKey);}
}

✅ 4.4 注意事项
问题解决方案
并发重复提交Token删除需原子操作(Lua脚本)
Token泄露或伪造Token绑定用户ID,校验一致性
幂等Key设计不当使用userId+skuId+时间戳业务单号
库存扣减重复库存流水表使用唯一索引防重
分布式事务使用本地事务 + 消息队列最终一致性(如RocketMQ)

✅ 4.5 总结一句话

*下单接口幂等性 = 前端防重(Token) + 服务端防重(唯一索引) + 状态机控制 + 分布式锁兜底


总结

幂等性是构建可靠、容错系统的基石,通过数学定义和工程实践(如Token机制、条件更新)确保重复操作无副作用。核心目标:“一次或多次,结果不变”

http://www.dtcms.com/a/312012.html

相关文章:

  • 雷卯针对香橙派Orange Pi RV2开发板防雷防静电方案
  • kotlin小记(1)
  • Waterfox水狐浏览器、火狐浏览器外观修改
  • Dice Combinations(Dynamic Programming)
  • 【Bug记录】关于copy的表不能copy主键和index的解决办法
  • python:以支持向量机(SVM)为例,通过调整正则化参数C和核函数类型来控制欠拟合和过拟合
  • SM2椭圆曲线密码算法原理与纯C语言实现详解
  • #Linux内存管理# 用一个案例详细介绍ARMv7-A架构 缺页中断处理的原理
  • ARMv8/v9架构FAR_EL3寄存器介绍
  • imx6ull-驱动开发篇6——Linux 设备树语法
  • P10816 [EC Final 2020] Namomo Subsequence|普及+
  • 堆----1.数组中的第K个最大元素
  • [buuctf-misc]喵喵喵
  • Linux学习--数据结构
  • 前端-移动Web-day3
  • 基于springboot的郑州旅游景点推荐系统
  • Kotlin单例模式懒汉模式:LazyThreadSafetyMode.SYNCHRONIZED(2)
  • 多线程(二) ~ 线程核心属性与状态
  • C#中对于List的多种排序方式
  • LeeCode 88. 合并两个有序数组
  • DeepSpeed - 超大LLM分布式训练框架 ZeRO技术
  • Python day32
  • 力扣 二叉树遍历 中序/前序/后序(递归和迭代版)
  • dbt中多源数据的处理
  • 混合嵌入与置信度增强:新一代RAG技术如何提升LLM性能
  • 1.6 vue 监听
  • JavaScript 原始值与引用值
  • SQL语言学习(group by,having)
  • PyTorch 中 Tensor 统计学函数及相关概念
  • 基于单片机一氧化碳CO检测/煤气防中毒检测报警系统