幂等性

目录

1.转账提现

2.发货系统


幂等性在我们的实际开发中是比较常见的,例如转账提现、订单发货系统等。今天,我们就分这两种场景对幂等性进行讨论:

1.转账提现

假如让我们实现支付宝和银行的转账提现需求,你会怎么做呢?

首先我们看一下示意图:

用户登录支付宝发起提现请求,支付宝调用银行的出款接口,再将相关记录落入数据库。正常情况下,这个流程没有问题,可是如果有一天银行的出款接口超级慢,或者干脆挂掉了,应该如何处理呢?我们如果直接提示,“出款失败,请明天再来或者稍后再试”这样的字样显示是非常不友好的,会带来用户的损失。正确的做法应该是?

  1. 假如是因为接口超时导致无法出款的话,我们可以做一次接口重试。当然,银行的接口必须满足幂等性,防止重复提交导致重复扣款。此时的幂等性可以使用一个提交的版本号,银行系统遇到和之前处理请求的版本号相同或者小的版本号,就不做处理。
  2. 银行系统接口假如没有实现幂等性呢?这在现实中是非常常见的,此时我们可以给用户返回成功,保存用户的请求,后面定时提交。

2.发货系统

电商行业的发货系统通常是这样的,用户提交订单,订单系统调用发货接口开始发货,并将相关记录落库。示意图如下:

发货系统提供的发货接口为:

  • 接口地址:http://127.0.0.1:9080/trans/sendOrder?order=1
  • 接口参数:order=1 订单号为1
  • 接口方法:对订单1进行发货

当系统页面很卡顿的时候,用户在页面连续点击了多次相同的请求,会出现什么结果呢?如果不做幂等性处理,有可能多次调用发货系统,导致一个订单发货多次,此时我们可以使用版本号的方式解决该问题。首先新建一张订单表:

CREATE TABLE `order` (
  `orderid` VARCHAR(32) DEFAULT NULL,
  `ordertime` DATETIME DEFAULT NULL,
  `ordermoney` DECIMAL(20,0) DEFAULT NULL,
  `orderstatus` CHAR(1) DEFAULT NULL,
  `version` INT(11) DEFAULT NULL
) ENGINE=INNODB DEFAULT CHARSET=utf8;

利用数据库的事务的原子性,当对该表有更新操作的时候,同时更新版本号。例如存在如下未发货订单记录:

('1','2017-12-06 11:36:23','12','1',0)

1表示已经付款,2表示发货中。当订单执行发货的时候执行如下SQL:

update order set orderstatus=2,version=version+1 where orderstatus = 1 and version = 0 

这样通过引入版本号,就可以避免重复发货的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值