接口等幂性实施策略

什么是等幂性?

数学概念:即 f(n) = 1^n ,无论n为多少,f(n)的值永远为1。表示N次变换和1次变换的结果是相同的。

编程领域:是指用户对于同一操作发起的一次请求或者多次请求,接口最终得到的结果是一致的。其任意多次执行对资源本身所产生的影响均与一次执行的影响相同。

就是接口可重复调用,在调用方多次调用的情况下,接口最终得到的结果是一致的。有些接口可以天然的实现幂等性,比如查询接口,对于查询来说,你查询一次和两次,对于系统来说,没有任何影响,查出的结果也是一样。除了查询功能具有天然的幂等性之外,增加、更新、删除都要保证幂等性。

是服务提供者对客户端的一种保证,保证接口是满足幂等性的(即保证同一个接口多次调用对系统的影响一致)。如我在前端界面连续两次点击添加按钮,但是本意是只能添加一次就好,后端接口要保证第一次添加成功之后,第二次再添加时,不能再进行了,就算进行添加,也得保证操作后的结果和第一次操作后的结果是一样的。其目的是防止多次提交,数据重复入库,表单验证网络延迟重复提交等问题;

等幂的场景

前端重复提交:

1、同时多次点击订单新增按钮,如果不做等幂性处理,后台就有几条一模一样的数据。

解决:

①利用唯一索引:给订单表添加唯一索引,这种主要是通过数据库本身来校验是否主键冲突,当数据重复插入时,直接报SQL异常。

②先查询,后判断:入库时先查询是否存在该订单,有就返回提交成功,没有就插入数据。

③分布式锁:这里讲redis锁:用订单号来作为锁的key,首先去redis缓存中查找是否有该key,如果不存在,则向redis中增加该订单号key,添加成功之后删除该订单号的key。这样新增其他订单号都不受这个锁的影响。

④token 机制:前端每次进入的时候都会获取到一个token值,后端会将这个token存储在redis中,然后提交的时候一起将token传过去,检验如果是同一个token就可以插入数据库,如果不是同一个就返回失败。

接口超时重试:

2、A系统请求B系统支付接口进行支付,B系统接收到支付请求之后,进行扣款操作且扣款成功,但是在接口返回时超时了。在B系统没有做等幂处理情况下。此时如果A系统再向B系统发起支付申请重试时,对于客户来说同一笔交易发生多次扣款,造成客户损失,不符合幂等性原则(同一个订单,无论是调用了多少次,用户都只会扣款一次)

解决:

①利用唯一索引、先查询后判断:B系统在接口设计时,定义一个对于每笔订单都是唯一的流水号编号字段,同时在数据库中对该字段维护唯一约束。若A请求B网络超时,那么A可以不更换交易流水号,继续请求B系统对超时的交易进行重试,B系统在插入支付订单前,先检查一下是否之前已经处理该笔交易。如果未处理,则直接交易落地并进行处理。如果交易已经处理,则返回给A系统此时的交易状态和结果。

②状态机:订单具有自己的状态:订单首先有提交(0),付款中(1),付款成功(2),付款失败(3)。

update Order set orderStatus = 1 where OrderId = 'orderid' and orderStatus = 0

当orderStatus 处于0,1两种状态时,对订单执行0->1 的状态流转操作应该是具有幂等性的。这时候需要在执行update操作之前检测orderStatus是否已经=1,如果已经=1则直接返回true即可。

但是如果此时orderStatus = 1,再进行订单状态0->1 时操作就无法成功,但是幂等性是针对同一个请求的,也就是针对同一个requestid保持幂等。

消息重复消费:

消息中间件,消息重复消费。

如何保证等幂性

1、唯一索引:给表加唯一索引,次方法最简单,当数据重复插入时,直接报SQL异常;

2、分布式锁:

3、先查询后判断:入库时先查询是否有该数据,无插入,否则不插入;

4、token 机制:

5、状态机

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值