幂等性的定义
任意多次执行所产生的影响均与一次执行的影响相同,这是幂等性的核心特点。其实在我们编程中主要操作就是CURD,其中读取(Retrieve)操作和删除(Delete)操作是天然幂等的,受影响的就是创建(Create)、更新(Update)。
常见的发生重复请求的场景
对于业务中需要考虑幂等性的地方一般都是接口的重复请求,重复请求是指同一个请求因为某些原因被多次提交。导致这个情况会有几种场景:
前端重复提交:提交订单,用户快速重复点击多次,造成后端生成多个内容重复的订单。
接口超时重试:对于给第三方调用的接口,为了防止网络抖动或其他原因造成请求丢失,这样的接口一般都会设计成超时重试多次。
消息重复消费:MQ消息中间件,消息重复消费。
幂等性的解决方案
前端控制
对于和web端交互的接口,我们可以在前端拦截一部分,例如防止表单重复提交,按钮置灰、隐藏、不可点击等方式。
后端控制
Token机制
大概流程,token方案要注意查询和删除的原子性

主要流程就是:
服务端提供了发送token的接口。我们在分析业务的时候,哪些业务是存在幂等问题的,就必须在执行业务前,先去获取token,服务器会把token保存到redis中。(微服务肯定是分布式了,如果单机就适用jvm缓存)。
然后调用业务接口请求时,把token携带过去,一般放在请求头部。
服务器判断token是否存在redis中,存在表示第一次请求,这时把redis中的token删除,继续执行业务。
如果判断token不存在redis中,就表示是重复操作,直接返回重复标记给client,这样就保证了业务代码,不被重复执行。
数据库唯一索引
这个就很简单了,建立唯一索引即可。
redis实现
大概流程

Redis实现的方式就是将唯一序列号作为Key,唯一序列号的生成方式和上面介绍的防重表的一样,value可以是你想填的任何信息。唯一序列号也可以是一个字段,例如订单的订单号,也可以是多字段的唯一性组合。当然这里需要设置一个 key 的过期时间,否则 Redis 中会存在过多的 key。
状态模式
状态模式,某一个状态能流转到另一个状态,从而保证幂等性。
具体可以查看上一篇文章: 订单流转之状态模式的设计与实现
总结
具体情况要根据不同的业务场景来进行权衡和选择,任何事情都没有银弹。





















![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)