• 使用最终一致性思想解决分布式事务


     //需求,下单流程需要调用库存服务扣减库存,调用积分服务扣减积分,调用奖励金服务扣减奖励金,调用优惠券服务使用优惠券,如果调用其中一个服务挂了,如何处理 分布式事务
        //伪代码
        @Transactional
        public ShopOrderMast creatOrderMast(OrderResq resq){
            boolean flgScore=false;//是否扣减积分成功
            boolean flgBlance=false;//是否使用奖励金抵扣成功
            boolean flgCoupon=false;//是否成功使用优惠券
            List<Item> list=null;//成功扣减商品的集合
            try {
                //调用库存服务扣减方法
                stockResp=A.subStock(itemList);
                if(stockResp==null || !stockResp.isSuccess){//或者有些公司封装成的是状态码
                    throw ex;//自己定义的异常
                }else {
                    list=stockResp.getList();//获取扣减成功的商品集合
    
                }
                //调用积分服务扣减积分
                ScoreResp=B.subScore(scoreList);
                if(ScoreResp==null || !ScoreResp.isSuccess){//或者有些公司封装成的是状态码
                    throw ex;//自己定义的异常
                }else {
                    flgScore=true;//积分扣减成功
    
                }
                //奖励金服务抵扣
                blanceResp=C.subBlance(balanceList);
                if(blanceResp==null || !blanceResp.isSuccess){//或者有些公司封装成的是状态码
                    throw ex;//自己定义的异常
                }else {
                    flgBlance=true;//奖励金扣减成功
    
                }
                //调用优惠券服务
                couponResp=D.useCoupon(coupOnId);
                if(couponResp==null || !couponResp.isSuccess){//或者有些公司封装成的是状态码
                    throw ex;//自己定义的异常
                }else {
                    flgCoupon=true;//成功使用优惠券
    
                }
    
            } catch (BaseException e) {
                if(CommonUtil.isNotNull(list)){//如果list有数据,证明这些库存扣减成功了,需要回滚
                    addStockResp=A.addStock(list);//调用库存回滚方法
                    if(addStockResp==null || !addStockResp.isSuccess){
                        //此时回滚还是失败的话,将记录存到日志表
                        logService.addLogData(requestUrl,JSON.toJSONString(list),JSON.toJSONString(addStockResp));
                    }
                }
                if(flgScore){//积分扣减成功了
                    addScoreResp=B.addScore(score);//调用积分回滚方法
                    if(addScoreResp==null || !addScoreResp.isSuccess){
                        //此时回滚还是失败的话,将记录存到日志表
                        logService.addLogData(requestUrl,JSON.toJSONString(score),JSON.toJSONString(addScoreResp));
                    }
                }
                if(flgBlance){//奖励金扣减成功了
    
                    addBlanceResp=C.addStock(blancelist);//调用奖励金回滚方法
                    if(addBlanceResp==null || !addBlanceResp.isSuccess){
                        //此时回滚还是失败的话,将记录存到日志表
                        logService.addLogData(requestUrl,JSON.toJSONString(list),JSON.toJSONString(addBlanceResp));
                    }
                }
                if(flgCoupon){ //如果优惠券使用成功了
                    addCouponResp=D.addStock(coupOnId);//调用优惠券回滚
                    if(addCouponResp==null || !addCouponResp.isSuccess){
                        //此时回滚还是失败的话,将记录存到日志表
                        logService.addLogData(requestUrl,JSON.toJSONString(list),JSON.toJSONString(addCouponResp));
                    }
                }
                throw e;
            } catch (Exception ex) {
                if(CommonUtil.isNotNull(list)){//如果list有数据,证明这些库存扣减成功了,需要回滚
                    addStockResp=A.addStock(list);//调用库存回滚方法
                    if(addStockResp==null || !addStockResp.isSuccess){
                        //此时回滚还是失败的话,将记录存到日志表
                        logService.addLogData(requestUrl,JSON.toJSONString(list),JSON.toJSONString(addStockResp));
                    }
                }
                if(flgScore){//积分扣减成功了
                    addScoreResp=B.addScore(score);//调用积分回滚方法
                    if(addScoreResp==null || !addScoreResp.isSuccess){
                        //此时回滚还是失败的话,将记录存到日志表
                        logService.addLogData(requestUrl,JSON.toJSONString(score),JSON.toJSONString(addScoreResp));
                    }
                }
                if(flgBlance){//奖励金扣减成功了
    
                    addBlanceResp=C.addStock(blancelist);//调用奖励金回滚方法
                    if(addBlanceResp==null || !addBlanceResp.isSuccess){
                        //此时回滚还是失败的话,将记录存到日志表
                        logService.addLogData(requestUrl,JSON.toJSONString(list),JSON.toJSONString(addBlanceResp));
                    }
                }
                if(flgCoupon){ //如果优惠券使用成功了
                    addCouponResp=D.addStock(coupOnId);//调用优惠券回滚
                    if(addCouponResp==null || !addCouponResp.isSuccess){
                        //此时回滚还是失败的话,将记录存到日志表
                        logService.addLogData(requestUrl,JSON.toJSONString(list),JSON.toJSONString(addCouponResp));
                    }
                }
                throw new BaseException(ex.getMessage(), ex);
            }
    
        }

    //每天观察日志表看看有没异常,调用哪个方法,哪个接口出了异常,最后人工介入

    日志表设计如下:

  • 相关阅读:
    面经
    Onedrive云盘程序——OneManager小白设置指南
    Docker 命令
    Linux 命令
    Spring boot 返回参数移除null属性
    Springboot
    正则
    JVM内存模型
    缓冲和缓存的区别
    SpringBoot如何优雅的将静态资源配置注入到工具类中
  • 原文地址:https://www.cnblogs.com/yangxiaohui227/p/10677272.html
Copyright © 2020-2023  润新知