凌晨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系列,欢迎关注!
本文分享自微信公众号 - 路人甲Java(javacode2018)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
来源:oschina
链接:https://my.oschina.net/u/563890/blog/4367339