幂等相关

一、为什么要做幂等
案例:618刚到零点,小明就在淘宝购物车选择好商品,点击提交订单按钮,选择好支付方式,点了在支付宝收银台页面点击立即付款,因为人数众多,网络反应较慢,小明担心自己的商品被抢购一空,于是不断的点击立即付款按钮,此时支付宝应该只扣一次款,如果点击一次扣一次款,支付宝早就炸了。。。

二、幂等概念

1、幂等是指在多个同样的交易指令或请求同时或者先后到达后台,即使重复执行,系统也必须始终提供一致的状态,而不能有其他的副作用

2、幂等特点:
幂等不仅仅只是一次(或多次)请求对资源没有副作用(比如查询数据库操作,没有增删改,因此没有对数据库有任何影响)。
幂等还包括第一次请求的时候对资源产生了副作用,但是以后的多次请求都不会再对资源产生副作用。
幂等关注的是以后的多次请求是否对资源产生的副作用,而不关注结果。

三、什么情况下需要做幂等
1、用户重复提交:用户在APP上连续点击了多次提交订单,后台应该只产生一个订单
2、网络重发:向支付宝发起支付请求,由于网络问题或系统BUG重发,支付宝应该只扣一次钱
3、消息重发:B系统异步通知A系统,通知失败,B系统会重新通知A系统,直到通知成功,A系统需要支持幂等。
4、系统间重试:A系统调用B系统失败,A系统根据业务需要,有重试机制,会不断的调用B系统,直到B系统返回成功,B系统需要支持幂等。
5、异步和实时同时返回:A系统调用B系统,当B系统异步通知A与实时响应A同时返回时,A系统数据库的更新需要支持幂等;
6、预下单、确认支付、记账、补偿、退款

四、幂等的实现

1、需要通过唯一的业务单号来保证幂等。也就是说相同的业务单号,认为是同一笔业务。使用这个唯一的业务单号来确保,后面多次的相同的业务单号的处理逻辑和执行效果是一致的。以支付为例(在不考虑并发的情况下)
①先查询一下订单是否已经支付过
②如果已经支付过,则返回支付成功;如果没有支付,进行支付流程,修改订单状态为‘已支付’。

2、上述的保证幂等方案是分成两步的,第②步依赖第①步的查询结果,无法保证原子性的。在高并发下就会出现下面的情况:第二次请求在第一次请求第②步订单状态还没有修改为‘已支付状态’的情况下到来。所以在高并发场景下,幂等的实现逻辑需要把查询和变更状态操作加锁,将并行操作改为串行操作。

3、在某些场景下,加锁会影响执行效率,所以可以选择把业务单号加上唯一索引,在并发的场景中,只有第一笔插入的交易请求能够成功,后续的请求都会因为触发数据库的唯一索引而失败,然后捕获这个异常就可以。

五、幂等的缺点

增加了额外控制幂等的业务逻辑,复杂化了业务功能;
把并行执行的功能改为串行执行,降低了执行效率。

猜你喜欢

转载自blog.csdn.net/weixin_40966030/article/details/107866784