接口的幂等性问题

151 阅读2分钟

一、产生幂等性问题的简单场景

假设场景:正在开发领取红包的功能,每人只能领取一次红包,点击按钮之后,服务端处理发红包请求,返回结果后按钮置灰,用户之后不能再领取红包。

正常流程如下

graph LR

请求发红包接口 --> 校验状态

校验状态 -- 未领取 --> 改变状态为已领取 --> 后续账户加钱服务

校验状态 -- 已领取 --> 拒绝请求

如果有人绕过前端直接请求接口,同时发出多个请求,由于状态校验更改用户状态存在时间差,会有多个请求同时走到第一个分支,这样就会出现用户多次领取红包的情况,于是出现了幂等性问题。

二、什么是幂等性

这个概念来自于数学 f(x)=f(f(x))f(x) = f(f(x)) ,在计算机领域可以理解为:一次请求和多次请求同一个资源产生相同的副作用。

用这个概念来看一般情况下(不考虑复杂SQL逻辑,唯一索引等情况),常见数据库的 增删改查 操作的幂等性

指定参数查询:幂等。查询参数不变,则结果不变

按Id删除记录:幂等。多次删除同一记录和单次删除同一记录结果相同

增加一条记录:非幂等。多次请求会多次增加记录

修改一条记录:需要讨论。SET a=1 为幂等,SET a=a+1 为不幂等

三、为什么需要幂等性

避免出现各种意料之外的情况: 发放超量用户奖励、扣减库存超额、数据库记录与实际业务对不上等等。

四、何时处理接口幂等性

  1. 设计请求时,用户同样参数的请求本应只有一次影响

有些业务场景下,用户请求了两次,造成了两次影响,但这两次完全可以看作独立请求,比如点击一次攻击一次怪物,两次点击就不能算作一次攻击

  1. 多次请求会造成非预期的结果

比如查询 get 请求,影响不大的情况下一般不做幂等处理

五、如何处理幂等性问题

前端的交互细节是第一道保障,后端是最后兜底的最重要保障。

前端常见幂等性实现: 按钮置灰、页面重定向;

后端常见幂等性实现: 业务逻辑层加锁、JUC提供的并发控制、数据库唯一索引去重、业务表加状态字段、单次请求周期唯一Id等等。

这里不细讲是因为离开业务谈幂等处理意义不大,前期要深刻理解剖析业务逻辑,一定要根据自己的业务特点去找合适的幂等方案,而不是刻意去八股文里找方案。