美文网首页
编程式事务-网络调用-@Transactional-耗尽数据库连

编程式事务-网络调用-@Transactional-耗尽数据库连

作者: AC编程 | 来源:发表于2021-12-31 14:49 被阅读0次

一、核心代码

   @Resource
    private TransactionTemplate template;

    /**
     * 转账
     * 备注:本方法不要加@Transactional注解,事务由编程式事务TransactionTemplate手动控制,理由如下:
     * 1、如果本方法加@Transactional注解,一进该方法就会从数据库连接获取一个连接(即使没有和数据库相关的操作)
     * 2、当执行代码[alipayClient.certificateExecute(request)]调用支付宝转账接口时,如果出现不可控因素,导致io或者网络阻塞,
     * 就会导致事务无法提交,连接也就会一直被该请求占用,出现数据量连接池被耗尽。
     * 3、因此,将需要控制事务的代码放入TransactionTemplate.execute里控制事务
     * @param aliPayTrans
     * @return
     */
    @Override
    public boolean trans(AliPayTrans aliPayTrans) {
        if(aliPayTrans == null){
            log.error("aliPayTrans为null");
            return false;
        }

        if(aliPayTrans.getStatus()== AliPayStatusEnum.SUCCESS){
            log.info(aliPayTrans.getId()+":该笔订单已完成转账,不需要重复转账");
            //保持接口幂等性,返回true
            return true;
        }

        AlipayClient alipayClient = aliPayClientConfig.geAliPayClient();

        AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();

        AliPayTransVO transVO = new AliPayTransVO();
        transVO.setOutBizNo(aliPayTrans.getId()+"");
        transVO.setTransAmount(aliPayTrans.getTransAmount());

        transVO.setProductCode(aliPayTrans.getProductCode());
        transVO.setBizScene(aliPayTrans.getBizScene());

        transVO.setOrderTitle(aliPayTrans.getOrderTitle());
        transVO.setRemark(aliPayTrans.getRemark());

        //收款方信息
        AliPayPayeeVO payPayeeVO = new AliPayPayeeVO();
        payPayeeVO.setIdentity(aliPayTrans.getPayeeIdentity());
        payPayeeVO.setName(aliPayTrans.getName());
        payPayeeVO.setIdentityType(aliPayTrans.getIdentityType());
        transVO.setAliPayPayeeVO(payPayeeVO);

        //转账业务请求的扩展参数
        AliPayBusinessParamsVO aliPayBusinessParamsVO = new AliPayBusinessParamsVO();
        aliPayBusinessParamsVO.setSubBizScene(aliPayTrans.getBusinessParams());
        transVO.setAliPayBusinessParamsVO(aliPayBusinessParamsVO);

        String bizContent = JSON.toJSONString(transVO);
        request.setBizContent(bizContent);

        try {
            //调用支付宝转账接口
            AlipayFundTransUniTransferResponse response = alipayClient.certificateExecute(request);

            // 编程式事务,手动控制哪些代码块要加事务控制
            template.execute((TransactionCallback<Object>) transactionStatus -> {
                //保存转账结果
                AliPayTransResponse transResponse = new AliPayTransResponse();
                BeanUtil.copyProperties(response, transResponse);
                transResponse.setBizNo(response.getOutBizNo());
                aliPayTransResponseService.add(transResponse);

                //更新转账状态
                aliPayTransService.updateStatusById(transResponse.getBizNo(),transResponse.getStatus());

                return true;
            });

            if(response.isSuccess()){
                log.info("转账调用成功");
                return true;
            } else {
                log.error("转账调用失败:{}",response);
                return false;
            }
        }catch (Exception e){
            log.error(e.getMessage());
        }
        return true;
    }

二、推荐阅读

系统性能优化之编程式事务

相关文章

网友评论

      本文标题:编程式事务-网络调用-@Transactional-耗尽数据库连

      本文链接:https://www.haomeiwen.com/subject/loigqrtx.html