“接口幂等性”的版本间的差异
Jihongchang(讨论 | 贡献) (→引出问题) |
Jihongchang(讨论 | 贡献) (→解决方案) |
||
第35行: | 第35行: | ||
− | === | + | |
+ | === 传统解决方案 === | ||
传统办法是代码增加前置判断<syntaxhighlight lang="java"> | 传统办法是代码增加前置判断<syntaxhighlight lang="java"> | ||
if (!员工已调薪) { | if (!员工已调薪) { | ||
进行调薪 | 进行调薪 | ||
} | } | ||
− | </syntaxhighlight> | + | </syntaxhighlight>比如通过一些数据库中的标识发现这个员工是否在最近已经调过新了,基于这种业务上的考量限制再次进行这个员工的调薪操作; |
+ | |||
+ | 或者在这个员工的记录上记录上一次调薪的时间做基于业务逻辑的判断 | ||
+ | |||
+ | |||
+ | |||
+ | === 传统解决方案带来的问题 === | ||
+ | 需要前置判断的地方太多了,容易遗漏,和业务代码耦合在一起,影响开发效率,这种公共功能的需求实现做统一的抽象处理更好 | ||
+ | |||
+ | |||
+ | |||
+ | === 通用解决方案 === | ||
+ | 需要一种无侵入的幂等解决方案,构建'''<big>幂等表</big>'''是通用解决方案,让开发人员专心业务逻辑实现 |
2023年3月5日 (日) 10:22的版本
https://www.bilibili.com/video/BV1J44y1k7Se
什么是幂等性
发一次接口调用与发多次相同的接口消息都能得到与预期相符的结果
作为前端的应用,应用系统往往需要和后台的数据服务进行交互,在这个交互的过程中通常会选择 RESTful 或者 RPC 的方式进行调用。
在这个过程中,以目前主流的 RESTful 为例:
在实际的开发过程中会遇到这样的情况——系统和系统之间(这里指的就是应用系统和数据服务)是通过网络来进行数据传输的,只要是网络就可能出现网络抖动的情况,那么为了保证系统的高可靠性,作为前端的调用系统,可能会增加像 Spring Retryable 这样的组件,通过不断重试发送相同的调用来尽可能地提高系统的可靠性,这是日常开发中非常常见的一种使用方式。
但是这种使用方式会带来一种附加的问题:作为后台服务,必须要考虑幂等性。
具体案例
PUT https://xxxxx.com/employee/salary {"id":"1","incr_salary":500}
这是一个 RESTful 接口,接口的作用是对 id=1 的员工工资上调 500
//查询1号员工数据
Employee employee = employeeService.selectById(1);
//更新工资
employee.setSalary(employee.getSalary() + incrSalary);
//执行更新语句
employeeService.update(employee);
这样实现看上去没有问题,但如果放在前面描述过的应用 Spring Retryable 这样的组件的系统和系统之间进行调用的环境中就没有考虑到幂等性的处理。
引出问题
如果真的像上面代码中那样的简单实现,前端调用系统每重发一次请求,1号员工的工资就会上调500,这种情况就是一般说的幂等性被破坏了。
传统解决方案
传统办法是代码增加前置判断
if (!员工已调薪) {
进行调薪
}
比如通过一些数据库中的标识发现这个员工是否在最近已经调过新了,基于这种业务上的考量限制再次进行这个员工的调薪操作;
或者在这个员工的记录上记录上一次调薪的时间做基于业务逻辑的判断
传统解决方案带来的问题
需要前置判断的地方太多了,容易遗漏,和业务代码耦合在一起,影响开发效率,这种公共功能的需求实现做统一的抽象处理更好
通用解决方案
需要一种无侵入的幂等解决方案,构建幂等表是通用解决方案,让开发人员专心业务逻辑实现