凌晨2点,正在做梦,突然接到了技术总监的电话:明天来公司收拾收拾,办理离职!
说实话当时我头脑一片空白,直接懵了。
第二天到公司,才知道我写的一段代码,昨天一天让公司损失了100多万,被定性为重大事故,导致了我直接被炒鱿鱼,而我的一些领导也受到了牵连,让我十分愧疚。
这个业务应该很多人都会遇到,所以拿出来分享一下,避免大家踩坑。
我们公司是做投资理财的,用户可以充值、投资、提现,充值这块是我做的,使用第三方支付进行充值,过程如下:
step1:用户网站中输入充值金额
step2:后端创建充值订单入库,此时订单是待支付状态
step3:跳转到第三方支付页面,输入银行卡,然后确认支付
step4:第三方支付通过我方提供的回调接口异步将充值结果告知我方
问题出在了step4,逻辑如下:
-
//返回通知处理结果,true:处理成功;false:处理失败,第三方会继续重试
-
public boolean rechargeNotice(第三方支付充值结果){
-
try{
-
//第三方充值结果中包含了我方的订单id,从db中获取充值订单信息
-
OrderModel order = this.getOrderById(订单id);
//@1
-
//判断订单状态是否是待支付状态
-
if(订单状态 == 待支付状态){
//@2
-
//将订单状态置为充值成功
-
order.status(充值成功);
-
orderService.update(order);
-
//用户账户可用余额增加
-
this.accountService.incrBalance(用户id,充值金额);
-
return
true;
-
}
else{
-
//订单已处理过,返回true
-
return
true;
-
}
-
}catch(Exception e){
-
//记录异常信息,返回通知失败
-
return
false;
-
}
-
}
昨天由于网络不稳定,第三方支付对于多笔订单,产生了并发通知的情况,并发情况时,上面逻辑是有问题的。
同一笔订单,同时进行2次通知,此时都会走到@1,此时看到order的状态都是待支付状态,然后都会进入@2,最后导致账户余额重复增加了,最后导致,充值1000,账户余额增加2000,用户发现系统有这个bug,然后他们直接去提现了,导致公司重大损失,晚上公司对账发现了这个问题,技术总监进行了紧急修复。
这个问题,就是我们常说的幂等性的问题,是非常非常重要的一个技术点,所以大家一定要吃透,在日常开发中要时刻考虑幂等性的问题,以减少这种不必要的损失。
关于幂等性的,之前写过一篇文章:聊聊接口的幂等性,看过之后,本文中的问题,大家可以轻松解决。
更多好文章
世界上最好的关系是相互成就,点赞转发 感恩开心????
路人甲java
▲长按图片识别二维码关注
路人甲Java:工作10年的前阿里P7,所有文章以系列的方式呈现,带领大家成为java高手,目前已出:java高并发系列、mysql高手系列、Maven高手系列、mybatis系列、spring系列,正在连载springcloud系列,欢迎关注!
转载:https://blog.csdn.net/likun557/article/details/106596146