《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 blog.csdn.net/qq_30285985/article/details/114118521 「叁滴水」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注微信公众号:【芋道源码】有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

前言

在订单的状态发生改变后,支付宝会通过异步方式同志商家服务器。商家服务器需要返回success这7个字符,如果不是,则会不断重复发送。微信也是如此,必须需要商家服务器的正确反馈。既然这样,在回调接口就需要进行幂等处理。

一、什么是幂等?

幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。

细想一下回调接口一般会这样处理:

  1. 查看订单是否存在。
  2. 修改订单状态。
  3. 如果是支付成功状态,则进行发货。

这种逻辑本身是没有什么问题的,但是它不是一个幂等接口,如果收到好几次订单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修改成功。修改成功的线程进行发货即可。

如果思路有什么缺点,或者您还有更好的实现方式,请留言点评。

文章目录
  1. 1. 前言
  2. 2. 一、什么是幂等?
  3. 3. 二、如何进行幂等处理