我被炒鱿鱼了!

凌晨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,然后他们直接去提现了,导致公司重大损失,晚上公司对账发现了这个问题,技术总监进行了紧急修复。

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

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

更多好文章

  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系列,欢迎关注!

展开阅读全文
©️2020 CSDN 皮肤主题: 精致技术 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值