飞道的博客

我被炒鱿鱼了!

257人阅读  评论(0)

凌晨2点,正在做梦,突然接到了技术总监的电话:明天来公司收拾收拾,办理离职!

说实话当时我头脑一片空白,直接懵了。

第二天到公司,才知道我写的一段代码,昨天一天让公司损失了100多万,被定性为重大事故,导致了我直接被炒鱿鱼,而我的一些领导也受到了牵连,让我十分愧疚。

这个业务应该很多人都会遇到,所以拿出来分享一下,避免大家踩坑。

我们公司是做投资理财的,用户可以充值、投资、提现,充值这块是我做的,使用第三方支付进行充值,过程如下:

step1:用户网站中输入充值金额

step2:后端创建充值订单入库,此时订单是待支付状态

step3:跳转到第三方支付页面,输入银行卡,然后确认支付

step4:第三方支付通过我方提供的回调接口异步将充值结果告知我方

问题出在了step4,逻辑如下:


   
  1. //返回通知处理结果,true:处理成功;false:处理失败,第三方会继续重试
  2. public boolean rechargeNotice(第三方支付充值结果){
  3.     try{
  4.          //第三方充值结果中包含了我方的订单id,从db中获取充值订单信息
  5.         OrderModel order = this.getOrderById(订单id);  //@1
  6.          //判断订单状态是否是待支付状态
  7.          if(订单状态 == 待支付状态){  //@2
  8.              //将订单状态置为充值成功
  9.             order.status(充值成功);
  10.             orderService.update(order);
  11.              //用户账户可用余额增加
  12.             this.accountService.incrBalance(用户id,充值金额);
  13.              return  true;
  14.         } else{
  15.              //订单已处理过,返回true
  16.              return  true;
  17.         }
  18.     }catch(Exception e){
  19.          //记录异常信息,返回通知失败
  20.          return  false;
  21.     }
  22. }

昨天由于网络不稳定,第三方支付对于多笔订单,产生了并发通知的情况,并发情况时,上面逻辑是有问题的。

同一笔订单,同时进行2次通知,此时都会走到@1,此时看到order的状态都是待支付状态,然后都会进入@2,最后导致账户余额重复增加了,最后导致,充值1000,账户余额增加2000,用户发现系统有这个bug,然后他们直接去提现了,导致公司重大损失,晚上公司对账发现了这个问题,技术总监进行了紧急修复。

这个问题,就是我们常说的幂等性的问题,是非常非常重要的一个技术点,所以大家一定要吃透,在日常开发中要时刻考虑幂等性的问题,以减少这种不必要的损失。

关于幂等性的,之前写过一篇文章:聊聊接口的幂等性,看过之后,本文中的问题,大家可以轻松解决。

更多好文章

  1. spring系列

  2. Java高并发系列(共34篇)

  3. MySql高手系列(共27篇)

  4. Maven高手系列(共10篇)

  5. Mybatis系列(共12篇)

  6. 聊聊db和缓存一致性常见的实现方式

  7. 接口幂等性这么重要,它是什么?怎么实现?

  8. 泛型,有点难度,会让很多人懵逼,那是因为你没有看这篇文章!

世界上最好的关系是相互成就,点赞转发 感恩开心????

路人甲java

▲长按图片识别二维码关注

路人甲Java:工作10年的前阿里P7,所有文章以系列的方式呈现,带领大家成为java高手,目前已出:java高并发系列、mysql高手系列、Maven高手系列、mybatis系列、spring系列,正在连载springcloud系列,欢迎关注!


转载:https://blog.csdn.net/likun557/article/details/106596146
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场