ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

修改单例属性引发的血案

2021-02-25 18:01:34  阅读:138  来源: 互联网

标签:OperationService VerificationService 血案 private tradeParam 单例 tradeService publi


背景

最近接触的一些系统中遇到一个问题,一个交易的服务对外提供了支付和退款两种能力,但是发现运行时交易的服务走了退款。
原因是spring容器管理的一个对象service 属性运行时被改变,导致上下流程对不上的问题,多业务链路并发时引发运行时属性错乱,导致 支付和退款行为混淆
下面是大体代码样例。记录下问题原因

样例

1、定义一个核心支付服务

public interface CoreService {

    public BaseResult trade(TradeParam tradeParam);
}

2、抽象两个业务单元 验证和执行


public interface TradeService extends CoreService{

    public VerificationService getVerificationService();

    public void setVerificationService(VerificationService VerificationService);

    public OperationService getOperationService();

    public void setOperationService(OperationService OperationService);
}

3、实现共享逻辑代码

@Service
public class TradeServiceImpl implements TradeService{

    private VerificationService verificationService;

    private OperationService operationService;

    @Override
    public VerificationService getVerificationService() {
        return this.operationService;
    }

    @Override
    public void setVerificationService(VerificationService verificationService) {
        this.verificationService=verificationService;
    }

    @Override
    public OperationService getOperationService() {
        return verificationService;
    }

    @Override
    public void setOperationService(OperationService OperationService) {
        this.operationService = operationService;
    }

    @Override
    public BaseResult trade(TradeParam tradeParam) {
        getVerificationService().verification(tradeParam);
        getOperationService().operate(tradeParam);
        return null;
    }
}

4、实现支付链路


public class PayServiceImpl implements CoreService{


    @Autowired
    @Qualifier("payVerificationService")
    private VerificationService payVerificationService;

    @Autowired
    @Qualifier("tradeService")
    private TradeService tradeService;

    @Autowired
    @Qualifier("payOperationService")
    private OperationService payOperationService;


    @Override
    public BaseResult trade(TradeParam tradeParam) {
        tradeService.setVerificationService(payVerificationService);
        tradeService.setOperationService(payOperationService);
        return tradeService.trade(tradeParam);
    }
}

5、实现退款链路

public class RefundServiceImpl implements CoreService{


    @Autowired
    @Qualifier("refundVerificationService")
    private VerificationService refundVerificationService;

    @Autowired
    @Qualifier("tradeService")
    private TradeService tradeService;

    @Autowired
    @Qualifier("refundOperationService")
    private OperationService refundOperationService;


    @Override
    public BaseResult trade(TradeParam tradeParam) {
        tradeService.setVerificationService(refundVerificationService);
        tradeService.setOperationService(refundOperationService);
        return tradeService.trade(tradeParam);
    }
}

经上方案实现落地后, 支付和退款业务并发时就有概率导致支付和退款运行时对应的实际逻辑单元混乱,导致要支付的实际退款,要退款的实际支付的事情发生。 因为tradeService服务是容器管理的单例,多链路并发修改了单例内的属性,导致运行时故障

方案

修改的方式有很多,最终只要保证运行时的节点数据不存在被覆盖的目的即可。
最简单的替换方案就是将两个set值的逻辑类去掉,改为bean初始化时注入,支付和退款各自初始化一个不同的tradeService即可

标签:OperationService,VerificationService,血案,private,tradeParam,单例,tradeService,publi
来源: https://blog.csdn.net/xupeng874395012/article/details/114096170

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有