面试必问:接口幂等性

共 2611字,需浏览 6分钟

 ·

2024-04-17 18:17

欢迎关注微信公众号:互联网全栈架构

总体介绍


幂等(Idempotence)是一个计算机领域中的概念,通俗来讲,如果用户对一个操作发起一次或者多次请求,得到的结果都是一样的,那么就认为这样的操作是幂等的。HTTP规范对于幂等的说明如下:

A request method is considered idempotent if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request.

幂等性主要是指重复请求的场景,比如:

  • 用户多次点击提交按钮
  • 由于网络原因触发了重试机制

  • 页面回退后再次提交

  • 消息重复消费


简单来讲,接口最终都是对于数据的操作,也就是数据库的增删改查(CRUD),我们来分析一下,在发起多次相同的请求时,这些操作的幂等性:

幂等性的解决方案


一、添加唯一索引

根据业务场景,在数据库表中添加唯一索引,这样的话,如果向数据库中插入已经存在的业务数据,系统就会抛出异常,避免了重复数据的插入。

比如一个订单系统,把订单号作为唯一索引,前端提交订单之前,请求发号器生成一个订单号,然后把订单号加入到请求头中,后端程序保存订单信息到数据库中,如果抛出异常,数据不会重复插入,但可以向用户返回下单成功的提示:

当然,这种方式完全依赖数据库的唯一索引特性,虽然很安全,很好地避免了数据重复问题,但把问题全部抛给了数据库层面,会导致性能问题,同时,即使是数据重复了,也提示下单成功,对于用户不太友好。

二、数据库乐观锁
在并发业务系统中,乐观锁也是经常采用的一种手段,而这种乐观锁的机制主要用于更新操作。基本的做法是在数据库表中添加一个version字段,每次更新操作都把此字段的值加一,并且在更新的时候做一下版本判断。

下面我们以一个实例来演示一下这种做法,假如订单表中的数据如下:

这时候,如果我们想更新订单号1003的金额为102,那么我们需要首先把这个订单号的version查出来,结果是5,然后再更新amount字段,像下面这个sql:

UPDATE orders SET amount=102,version=version+1 WHERE order_id=1003 AND version=5

在上面的更新语句中,WHERE条件把version=5也加上了,如果这个更新操作有重复请求,那么最终也只有一条sql能够真正更新数据,因为其中一条sql更新成功后,version就等于6了,其他的sql就没有满足条件的数据了。

三、使用redis+token

使用redis+token的机制来保证幂等性是非常常见的一种手段,需要前后端配合一起来实现,前端首先向后端请求一个token,后续的请求中再带上这个token,接下来服务器再判断redis中是否存在这个token,如果存在,则进行后续的业务操作,否则说明此请求为重复请求。

在高并发的场景下,有一个问题需要考虑,是在业务操作前删除token,还是在业务操作结束之后再删除token?

如果是在业务操作前删除token,如果业务操作执行失败了,但还没有向客户端返回处理结果,此时客户端又进行了重试,但此时token已经删除,那么重试的请求就不再进行业务操作了(比如生成订单这样的操作)。

如果先进行业务操作,再删除token呢?也会有问题,比如第一次的业务操作还没有结束,第二次请求又过来了,这时token还存在,所以第二次请求也会继续执行,显然这是不合理的。

一般情况下,可以采用先删除token的方式,因为这种方式的结果是没有进行业务操作,后续再重新获取token进行操作即可,相对而言要更合理一些。

三三

总结


接口幂等性是并发编程中非常重要的概念,也是各个公司面试中常问的一个问题,本文总结了常见的实现幂等性的几种方案,相对来讲,使用redis+token的方式是一种比较常见且有效的方式,可以满足很多场景的需求。

当然,也还有其它的些手段来实现这样的功能,包括创建去重表、状态机等,都是在应用层面或者数据库层面来实现,此处不再展开。

创作不易,烦请点赞分享,感谢!

鸣谢:
https://blog.csdn.net/A_art_xiang/article/details/132106309


推荐阅读:

十多年经验的老码农,竟然倒在了这个问题上:MySQL中的or是否走索引

浏览 26
96点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
96点赞
评论
收藏
分享

手机扫一扫分享

分享
举报