【什么是接口幂等性?为什么会产生这个问题?如何保证接口幂等性?】之前负责的项目报了一个问题,用户操作回退失效 。我们的设计里,操作回退是回到操作前的状态 。经过查看日志发现,用户之前的操作做了两次,也就是说提交操作的接口被调用了两次,导致之用户上一次的状态和这一次的状态是一样的,所以操作回退是没有问题的,问题出在了操作的接口被调用了两次 。
对于防止重复提交,是放在前端控制的,用户点击完按钮之后,后台返回成功的结果,按钮就不可见,实践证明,客户端的限制操作不是绝对可靠的 。
针对上面的场景,就引入了今天的问题,什么是接口幂等性?如何保证接口幂等性?
什么是接口幂等性?首先看看幂等性的概念:
幂等性原本是数学上的概念,用在接口上就可以理解为:同一个接口,多次发出同一个请求,必须保证操作只执行一次 。 调用接口发生异常并且重复尝试时,总是会造成系统所无法承受的损失,所以必须阻止这种现象的发生 。
比如下面这些情况,如果没有实现接口幂等性会有很严重的后果: 支付接口,重复支付会导致多次扣钱 ;订单接口,同一个订单可能会多次创建 。

文章插图
为什么会产生接口幂等性问题?那么,什么情况下,会产生接口幂等性的问题呢?
- 网络波动, 可能会引起重复请求
- 用户重复操作,用户在操作时候可能会无意触发多次下单交易,甚至没有响应而有意触发多次交易应用
- 使用了失效或超时重试机制(Nginx重试、RPC重试或业务层重试等)
- 页面重复刷新
- 使用浏览器后退按钮重复之前的操作,导致重复提交表单
- 使用浏览器历史记录重复提交表单
- 浏览器重复的HTTP请求
- 定时任务重复执行
- 用户双击提交按钮
如何保证接口幂等性?那么最关键的来了,如何保证接口幂等性?
解决办法分为两个方向,一个方向是客户端防止重复调用,一个是服务端进行校验 。当然,客户端防止重复提交并不是绝对可靠的,优点是实现起来比较简单 。
- 按钮只可操作一次
一般是提交后把按钮置灰或loding状态,消除用户因为重复点击而产生的重复记录,比如添加操作,由于点击两次而产生两条记录
- token机制
功能上允许重复提交,但要保证重复提交不产生副作用,比如点击n次只产生一条记录,具体实现就是进入页面时申请一个token,然后后面所有的请求都带上这个token,后端根据token来避免重复请求 。

文章插图
- 使用Post/Redirect/Get模式
在提交后执行页面重定向,这就是所谓的Post-Redirect—Get(PRG)模式,简单来说就是当用户提交连表单后,跳转到一个重定向的信息页面,这样就避免用户按F5刷新导致的重复提交,而且也不会出现浏览器表单重复提交的警告,也能消除按浏览器前进和后退导致同样重复提交的问题 。
- 在session存放特殊标志
在服务端,生成一个唯一的标识符,将它存入session,同时前端获取这个标识符的值将它写入表单的隐藏中,用于用户输入信息后点击一起提交,在服务器端,获取表单中隐藏字段的值,与session中的唯一标识符比较,相等说明是首次提交,就处理本次请求,然后将session中的唯一标识符移除,不相等则表示是重复提交,不再做处理 。
- 使用唯一索引防止新增脏数据
利用数据库唯一索引机制,当数据重复时,插入数据库会抛出异常,保证不会出现脏数据 。
- 乐观锁
如果更新已有数据,可以进行加锁更新,也可以设计表结构时使用乐观锁,通过version来做乐观锁,这样既能保证执行效率,又能保证幂等, 乐观锁的version版本在更新业务数据要自增
update table set version = version + 1 where id = #{id} and version = #{version}
示例: 当有重复请求的时候,第一个请求会获取当前商品的version版本号,得到的version为1,紧接着由于第一个请求还没更新商品的version,第二个请求获取的version依然也是1, 这时候第一个请求操作更新的时候带上version并作为条件并且自增更新,这时候商品的version就会变成2,当第二个请求去操作更新的时候明显version不一致导致更新失败 。
- select + insert or update or delete
推荐阅读
-
超模迷|超模IG为比基尼而生,每一张照片,都让人欲罢不能,身材绝对NO.1
-
-
女人漾|一袭蓝裙惹人怜爱,赵丽颖这是什么身材?腰围和头围差不多
-
中国网|?外汇管理局:9月我国外汇市场供求基本平衡 跨境资金流动总体稳定
-
天天快报|外国网友:以后你会哭的,苏-30模拟战4比0胜歼-20?印度人乐坏了
-
nadech|Nadech和Yaya升级为准夫妇,订婚钻戒5.5克拉,好友每人一条金链
-
苹果|iPhone 13无塑料包装盒曝光 网友:降低了华强北后封难度
-
股票行情|7月20日创业板IPO动态:可孚医疗获受理 捷强装备等4家企业首发过会
-
小宇说科技|均龄近60却看不出老态,不老男神同框!梁朝伟和梁家辉机场晒合影
-
「阿亮说菜谱」美食食谱:酸辣泡鸡爪、元宝红烧肉、金针菇卷肉、青椒爆炒牛肉
-
中年|小学生发明攻速暴击流刘邦,单挑肉盾刘邦,网友这出装咋想的
-
-
每日一鲜|2020淘宝天猫双十一1111元超级红包,养猫组队活动玩法
-
-
美味|葱爆肥牛,香嫩入味家常菜,营养美味好吸收,白领必备快手美味
-
daoda|交易异动!祥鑫科技:不存在应披露而未披露的重大事项 近3个交易日上涨27.54%
-
半岛都市报|高一新生军训晕倒不幸身亡,家长:学校救治不及时,教育局回应了!
-
年内|烈火烹油的公募定增:年内已逾180亿同比增超6倍
-
-