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

 //需求,下单流程需要调用库存服务扣减库存,调用积分服务扣减积分,调用奖励金服务扣减奖励金,调用优惠券服务使用优惠券,如果调用其中一个服务挂了,如何处理 分布式事务
    //伪代码
    @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);
        }

    }

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

 

日志表设计如下:

 

posted @ 2019-04-09 15:37  yangxiaohui227  阅读(177)  评论(0编辑  收藏  举报