需求:在放款成功后把通过接口上传规定格式的业务数据,必须不影响后面的主体业务!!
思路:线程调度实现,第一次正常触发,把失败的数据保存在数据库日志表收集起来,后续周期性的执行。自己调用自己,运用递归算法。
代码:
@Autowired
private ScheduledThreadPoolExecutor executorService ;
@PostConstruct
public void init(){
//0代表线程池里面允许维护的最小线程数
executorService = new ScheduledThreadPoolExecutor(0, new NamedThreadFactory("jzPaymentReslutHandleService"));
executorService.setMaximumPoolSize(1); //线程池里面允许最大的线程数
}
@PreDestroy
private void destory(){
executorService.shutdown(); //关闭线程调度
}
/**
* 在新的线程里面执行代码
*
* @author Rita
* @date 2019年7月23日
* @param callable 线程
*/
private <T> void executeInNewThread(Callable<T> callable) {
try {
if (executorService.getQueue().size() > 15) {
logger.error("********8的线程数超过15个,此次调度将会被忽略");
return;
}
executorService.submit(callable);
logger.info("********的线程,提交线程任务成功");
} catch (Exception e) {
logger.info("上********,提交线程任务失败");
logger.error("********的线程,提交线程任务失败:{}", e.getMessage());
}
}
//处理放款成功的业务代码
public void processForSuccess(ABC response, CDEtradeOrder) {
executeInNewThread(new Callable<Object>() {
@Override
public Object call() throws Exception {
//****************
try {
doSaveCustInfo(tradeOrder);
} catch (Exception e) {
logger.error("********上传失败:{}",e.getMessage());
}
return null;
}
});
//后续一些业务操做
}
private void doSaveCustInfo(ABC tradeOrder) {
txNewServiceImpl.doInTxNew( () -> {
AA custInfoLogBean = new AA ();
try {
BB joinShareReq = buildParam(tradeOrder);//构造接口参数
CC joinShareResp = joinShareService.saveCustInfo(joinShareReq);
if (joinShareResp != null && joinShareResp.isSuccess()) { // 成功的状态
custInfoLogBean.setRemarks("*******接口已经成功处理");
} else {
custInfoLogBean.setRemarks("******的接口处理失败");
}
BeanUtils.copyProperties(joinShareReq.getCustInfo(), custInfoLogBean);
custInfoLogBean.setStatus("SUCCESS");//更新状态为成功
} catch (Exception e) {
custInfoLogBean.setStatus("FAIL"); //更新状态为失败
}finally{
custInfoLogBeanMapper.insertSelective(custInfoLogBean);
}
list = custInfoLogBeanMapper.selectbyStatus(custInfoLogBean.getStatus());
if(CollectionUtils.isNotEmpty(list)){
doSaveCustInfoAtFuture(list);
}
return null ;
});
}
private void doSaveCustInfoAtFuture(List<CustInfoLogBean> custInfoLogBeanList) {
if (CollectionUtils.isEmpty(custInfoLogBeanList)) {
return;
}
executorService.schedule(new Callable<Object>() {
@Override
public Object call() throws Exception {
try {
for (AA bean : custInfoLogBeanList) {
try {
CC response = doSaveCustInfo(bean);
if (response != null && response.isSuccess()) {
bean.setRemarks("********接口已经成功处理");
bean.setStatus("SUCCESS");
} else {
bean.setRemarks("********接口处理失败");
bean.setStatus("FAIL");
}
bean.setUpdateTime(new Date());
} catch (Exception e) {
logger.error("********的接口处理出现异常:{}", e.getMessage());
} finally {
custInfoLogBeanMapper.insertSelective(bean);
}
list = custInfoLogBeanMapper.selectbyStatus(bean.getStatus());
if (CollectionUtils.isNotEmpty(list)) {
logger.info("********的接口没有处理,放到下一次再处理" + list.size());
doSaveCustInfoAtFuture(list);
} else {
logger.info("********的接口线程执行结束");
}
}
} catch (Exception e) {
logger.error("********接口线程执行失败");
}
return null;
}
}, 2, TimeUnit.SECONDS);
private JoinShareResponse doSaveCustInfo(CustInfoLogBean bean) {
JoinShareCustInfo custInfo = new JoinShareCustInfo();
BeanUtils.copyProperties(bean, custInfo);
JoinShareRequest joinShareReq = new JoinShareRequest();
joinShareReq.setCustInfo(custInfo);
JoinShareResponse response = joinShareService.saveCustInfo(joinShareReq);
return response;
}
private JoinShareRequest buildParam(LoanApplyTradeOrder tradeOrder) {
JoinShareCustoInfoVo vo = customerMapper.selectCustomerInfoByCondition(String.valueOf(tradeOrder.getIouId()),
String.valueOf(tradeOrder.getCustId()));
JoinShareRequest joinShareReq = new JoinShareRequest();
if (vo != null) {
JoinShareCustInfo custInfo = new JoinShareCustInfo();
if (!Objects.equals(null, vo.getStartDate())) {
custInfo.setStartDate(DateUtil.convertDateFormat(vo.getStartDate()));
}
if (!Objects.equals(null, vo.getEndDate())) {
custInfo.setEndDate(DateUtil.convertDateFormat(vo.getEndDate()));
}
custInfo.setSex(CardUtil.getSexByCard(vo.getCardNum()));
custInfo.setAge(String.valueOf(CardUtil.getAgeByCard(vo.getCardNum())));
// custInfo.setIncome(0); // ??
custInfo.setCustomerIdentity(""); // todo?
custInfo.setConsumptionPurpose("260001");
custInfo.setTdScore(""); // todo?
custInfo.setCardNum(vo.getCardNum());
joinShareReq.setCustInfo(custInfo);
BeanUtils.copyProperties(vo, custInfo);
return joinShareReq;
} else {
logger.info("buildParam方法中********为null");
throw new BusinessRuntimeException("********为null,iouId:" + String.valueOf(tradeOrder.getIouId())
+ "custId:" + String.valueOf(tradeOrder.getCustId()));
}
}