关于幂等性的定义和解决方案

幂等性的定义

任意多次执行所产生的影响均与一次执行的影响相同,这是幂等性的核心特点。其实在我们编程中主要操作就是CURD,其中读取(Retrieve)操作和删除(Delete)操作是天然幂等的,受影响的就是创建(Create)、更新(Update)。

常见的发生重复请求的场景

对于业务中需要考虑幂等性的地方一般都是接口的重复请求,重复请求是指同一个请求因为某些原因被多次提交。导致这个情况会有几种场景:
前端重复提交:提交订单,用户快速重复点击多次,造成后端生成多个内容重复的订单。
接口超时重试:对于给第三方调用的接口,为了防止网络抖动或其他原因造成请求丢失,这样的接口一般都会设计成超时重试多次。
消息重复消费:MQ消息中间件,消息重复消费。

幂等性的解决方案

前端控制

对于和web端交互的接口,我们可以在前端拦截一部分,例如防止表单重复提交,按钮置灰、隐藏、不可点击等方式。

后端控制

Token机制

大概流程,token方案要注意查询和删除的原子性

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

数据库唯一索引

这个就很简单了,建立唯一索引即可。

redis实现

大概流程

image.png
Redis实现的方式就是将唯一序列号作为Key,唯一序列号的生成方式和上面介绍的防重表的一样,value可以是你想填的任何信息。唯一序列号也可以是一个字段,例如订单的订单号,也可以是多字段的唯一性组合。当然这里需要设置一个 key 的过期时间,否则 Redis 中会存在过多的 key。

状态模式

状态模式,某一个状态能流转到另一个状态,从而保证幂等性。
具体可以查看上一篇文章: 订单流转之状态模式的设计与实现

总结

具体情况要根据不同的业务场景来进行权衡和选择,任何事情都没有银弹。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享