其他
接口的幂等性的N种考虑,你知道吗?
往期热门文章:
3、Spring Boot 2.4.0正式发布,全新的配置文件加载机制(不向下兼容)
4、Insert into select语句引发的生产事故!
目录
目录 前言 正文 1 接口幂等性 1.1 案例 2 解决方案 2.1 token机制 2.2 去重表 2.3 redis 的 SETNX键值 2.4 状态机幂 2.5 乐观锁(更新操作) 2.6 悲观锁(更新操作) 结语
前言
正文
1 接口幂等性
1.1 案例
2 解决方案
2.1 token机制
首先客户端先请求服务端,服务端生成token,每次请求生成的都是一个新的token(这个token一定要设置超时时间),将token存入redis当中,然后将token返回给客户端。 客户端携带刚刚返回的token请求服务端做业务请求。 服务端收到请求,做判断。 如果token在redis中,则直接删除该token,然后继续做业务请求。 如果token不在redis中,代表已经执行过当前业务了,则不执行业务。
2.2 去重表
首先客户端先请求服务端,服务端先将这次的请求信息存入一张mysql的去重表中,这张表要根据这次请求的其中某个特殊字段建立唯一索引,或者主键索引。 判断是否插入成功 如果插入成功,则继续做后续业务请求。 如果插入失败,则代表已经执行过当前请求。
1.mysql容错性,也就是mysql本身如果不是高可用的那么业务可能会受到影响: 2.既然是唯一索引,自然在写表的时候就没有办法用到changbuffer,每次都要从磁盘查出来判断再写入,对于一个高并发的接口来说,这些都是需要考虑的因素。
2.3 redis 的 SETNX键值
首先客户端先请求服务端,服务端将能代表这次请求业务的唯一字段以 SETNX 的方式存入redis,并设置超时时间,超时时间可以根据业务权衡。 判断是否插入成功 如果插入成功,则继续做后续业务请求。 如果插入失败,则代表已经执行过当前请求。
2.4 状态机幂
2.5 乐观锁(更新操作)
首先客户端先请求服务端,先查询出当前的version版本。 select version from .. where .. 根据version版本来做sql操作 UPDATE .. SET ... version=(version+1) WHERE .. AND version=version;
2.6 悲观锁(更新操作)
SELETE * FROM TABLE WHERE .. FOR UPDATE;
UPDATE TABLE SET ... WHERE ..;
COMMIT; # 提交事务