点击关注公众号,Java干货及时送达
作者:叁滴水
博客:https://blog.csdn.net/qq_30285985/
前言
当订单的状态发生改变后,支付宝通常会以异步的方式通知商家服务器。
推荐阅读:Spring Boot 接入支付宝!
商家服务器需要返回success
这 7 个字符,如果不是,则支付宝则会不断重复通知商家服务器。
微信支付也是如此,必须需要得到商家服务器的正确响应。既然这样,支付回调接口就需要进行幂等性处理。
一、什么是幂等?
幂等操作的特点是其任意多次执行,所产生的影响均与一次执行的影响相同。根性性的 服务高可用:幂等性设计 推荐看下。
细想一下回调接口一般会这样处理:
查看订单是否存在。
修改订单状态。
如果是支付成功状态,则进行发货。
这种逻辑本身是没有什么问题的,但是它不是一个幂等接口,如果收到好几次订单1001
支付成功的请求,则会对订单1001
的商品多次发货,这就导致了一个订单多次发货的现象,这种在电商开发时是灾难性的 bug。
因此,我们需要对此回调接口做一个处理,这样即使有很多重复请求都告诉商户服务器订单1001
支付成功,商户也只发一次货。
二、如何进行幂等处理
对于这种接口的幂等性处理,我也是思量了许久,最终决定再次使用修改状态的方式。另外,老大难的分布式锁与幂等性问题,这篇推荐看下。
具体实现方式如下:
1)订单表t_order
存在订单号1001
的订单是未支付
状态。
2)支付宝转账成功之后,通知商家服务器订单1001
转账成功。
3)商家服务器进行验签。
4)查看订单是否存在,以及基本信息是否一致。
5)修改此订单状态。通过update t_order set 状态=已支付 where order_id=1001 and 状态=未支付
6)通过以上 SQL 乐观锁的思想对发货进行控制,只有 SQL 执行修改成功才进行发货,否则不发货。
通过乐观锁可以有效的控制发货次数。并发控制--悲观锁和乐观锁详解,不管几次回调通知,只有当前订单是未支付状态并且成功修改成已支付状态之后才进行发货。
如下图,两个 SQL 一起执行修改订单状态,但肯定只会有一个 SQL 能够修改成功。

如果以上思路你觉得有什么缺点,或者你还有更好的实现方式,请留言分享。最后,关注公众号Java技术栈,在后台回复:面试,可以获取我整理的 Java 系列面试题和答案,非常齐全。
本文来自作者「叁滴水」投稿,谢谢分享,也欢迎爱好技术分享的各位技术朋友向「Java技术栈」投稿,让更多人看到,投稿方式:关注公众号「Java技术栈」在后台回复:投稿。
关注Java技术栈看更多干货
获取 Spring Boot 实战笔记!