一、核心代码
@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;
}
二、推荐阅读
系统性能优化之编程式事务
网友评论