Java异步定时任务

一、 application.yml配置

 invoiceCancelNotDeductResult: true #获取取消不抵扣结果任务开关
 invoiceCancelNotDeductResultCron: 0 0/1 * * * ? #获取取消不抵扣结果cron表达式。修改cron,需要修改锁有效期
 invoiceCancelNotDeductResultLockExpire: 178 #获取取消不抵扣结果锁有效期,3*60-2

二. 定时任务

 @Component
public class InvoiceCancelNotDeductResultScheduled {
    private static Logger logger = LoggerFactory.getLogger(InvoiceCancelNotDeductResultScheduled.class);

    @Autowired
    private InvoiceNotDeductScheduledService invoiceNotDeductScheduledService;


    @Autowired
    private ScheduledControll scheduledControll;

    @Value("${scheduled.invoiceCancelNotDeductResult}")
    private boolean invoiceCancelNotDeductResultFlag;
    /**
     * 发起不抵扣结果反馈锁有效期,2*60-2
     */
    @Value("${scheduled.invoiceCancelNotDeductResultLockExpire}")
    private String invoiceCancelNotDeductResultLockExpire;

    /**
     * 发起取消不抵扣结果反馈,获取任务号,3分钟一次
     * TODO:修改定时任务时间需要同步修改锁定的有效期。
     */
    @Scheduled(cron = "${scheduled.invoiceCancelNotDeductResultCron}")
    public void invoiceCancelNotDeductResult() {
        try {
            String requestId = String.valueOf(UUID.randomUUID());
            MDC.put("requestId", requestId);

            //获取配置文件开关
            if (!invoiceCancelNotDeductResultFlag) {
                logger.info("InvoiceCancelNotDeductResultScheduled 开关未开启,不执行发起取消不抵扣结果反馈定时任务");
                return;
            }

            //获取锁(定时任务支持集群,防止重复执行定时任务)
            if (StringUtils.isNotEmpty(invoiceCancelNotDeductResultLockExpire) && RegexMatchUtils.numericalMatch(invoiceCancelNotDeductResultLockExpire) && !scheduledControll.getInvoiceNotDeductResultScheduledLock(Integer.parseInt(invoiceCancelNotDeductResultLockExpire))) {
                logger.info("InvoiceCancelNotDeductResultScheduled 未能获取发起取消不抵扣结果反馈锁,不执行发起取消不抵扣结果反馈定时任务");
                return;
            }

            logger.info("定时任务++++++InvoiceCancelNotDeductResultScheduled 发起取消不抵扣结果反馈定时任务开始**************");
            long startTime = System.currentTimeMillis();
            invoiceNotDeductScheduledService.cancelNotDeductResultRet();
            logger.info("定时任务++++++++++InvoiceCancelNotDeductResultScheduled 发起取消不抵扣结果反馈定时任务结束,耗时:{}ms", System.currentTimeMillis() - startTime);

        } catch (Exception e) {
            //日志
            logger.info("InvoiceCancelNotDeductResultScheduled system error:", e);
        } finally {
            MDC.clear();
        }
    }
}

三. 具体实现

  1. 定时任务service接口
public interface InvoiceNotDeductScheduledService {
    /**
     * 发票不抵扣结果反馈
     */
    void notDeductResultRet();
    /**
     * 发票取消不抵扣结果反馈
     */
    void cancelNotDeductResultRet();
    
}

2… 定时任务实现类

package com.baiwang.platform.custom.service.impl.notdeduct;

import com.baiwang.platform.custom.common.enums.NotDeductEnum;
import com.baiwang.platform.custom.common.model.NotDeductRequest;
import com.baiwang.platform.custom.common.model.TScmVatNotDeduct;
import com.baiwang.platform.custom.service.notdeduct.ITScmVatNotDeductService;
import com.baiwang.platform.custom.service.notdeduct.InvoiceNotDeductScheduledService;
import com.baiwang.platform.custom.service.notdeduct.NotDeductBaseService;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * @ClassName InvoiceNotDeductScheduledServiceImpl
 * @Description 发票不抵扣定时任务
 * @Author yuan_wm
 * @Date 2019/12/10 下午3:27
 * @Version 1.0
 **/
@Service
public class InvoiceNotDeductScheduledServiceImpl implements InvoiceNotDeductScheduledService {
    private static final Logger logger = LoggerFactory.getLogger(InvoiceNotDeductScheduledServiceImpl.class);

    @Autowired
    private NotDeductBaseService notDeductBaseService;

    @Autowired
    private ITScmVatNotDeductService notDeductService;
    
	@Override
	public void cancelNotDeductResultRet() {
		// 获取发起取消不抵扣结果反馈的发票
		NotDeductRequest req = new NotDeductRequest();
		req.setDeductStatus(NotDeductEnum.NOT_DEDUCT_CANCLEING.getCode());// 4-取消不抵扣中
		PageInfo<TScmVatNotDeduct> page = notDeductService.queryCancelNotDeductListByCondition(req, 1, 1000);
		List<TScmVatNotDeduct> notDeductList = page.getList();
		if (notDeductList == null || notDeductList.size() == 0) {
			return;
		}
		cancelNotDeductResultRetLatch(notDeductList);
	}
	
	private void cancelNotDeductResultRetLatch(List<TScmVatNotDeduct> notDeductList) {
        int threshold = 50;
        int size = notDeductList.size(); // 根据状态值获取的记录数
        int count = size / threshold + (size % threshold == 0 ? 0 : 1);
        CountDownLatch latch = new CountDownLatch(count);
        try {
            while (notDeductList.size() >= threshold) {
                List<TScmVatNotDeduct> newList = new ArrayList<>();
                for (int i = 0; i < threshold; i++) {
                    newList.add(notDeductList.get(0));
                    notDeductList.remove(0);
                }
                notDeductBaseService.executeCancelNotDeductResultRet(newList, latch);
            }

            if (notDeductList.size() > 0) {
                notDeductBaseService.executeCancelNotDeductResultRet(notDeductList, latch);
            }
            latch.await();
        } catch (Exception e) {
            logger.error("cancelNotDeductResultRetLatch error", e);
        }
    }
}
  1. 具体业务接口
public interface NotDeductBaseService {
	Future<String> executeCancelNotDeductResultRet(List<TScmVatNotDeduct> notDeductList, CountDownLatch latch);
}
  1. 具体业务实现类
package com.baiwang.platform.custom.service.impl.notdeduct;

import com.baiwang.bop.respose.entity.input.ResultResponse;  
import com.baiwang.platform.custom.common.enums.NotDeductEnum;
import com.baiwang.platform.custom.common.model.NotDeductRequest;
import com.baiwang.platform.custom.common.model.TScmVatNotDeduct;
import com.baiwang.platform.custom.common.result.RestFulApiContants;
import com.baiwang.platform.custom.dao.CheckDeductDao;
import com.baiwang.platform.custom.dao.TScmVatDeductInfoMapper;
import com.baiwang.platform.custom.dao.TScmVatMainMapper;
import com.baiwang.platform.custom.dao.domain.TScmVatMain;
import com.baiwang.platform.custom.integration.bwcloud.JxChannelUtils;
import com.baiwang.platform.custom.service.notdeduct.ITScmVatNotDeductService;
import com.baiwang.platform.custom.service.notdeduct.NotDeductBaseService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;

@Service
public class NotDeductBaseServiceImpl implements NotDeductBaseService {
    private static final Logger logger = LoggerFactory.getLogger(NotDeductBaseServiceImpl.class);

    @Autowired
    private JxChannelUtils jxChannelUtils;

    @Autowired
    private ITScmVatNotDeductService notDeductService;

    @Autowired
    private TScmVatMainMapper tScmVatMainMapper;
    
	@Autowired
	private CheckDeductDao checkDeductDao;
	
	@Autowired
	private  TScmVatDeductInfoMapper notDeductInfoMapper;
    
    @Async
    @Override
	public Future<String> executeCancelNotDeductResultRet(List<TScmVatNotDeduct> notDeductList, CountDownLatch latch) {
		try {
	            TScmVatMain t = new TScmVatMain();
	            for (TScmVatNotDeduct notDeduct : notDeductList) {

	                ResultResponse deductibleResponse = jxChannelUtils.deductibleResult(notDeduct.getBuyerTaxno(),
	                        notDeduct.getCancelNoDeductTaskNo(), notDeduct.getInvKind(), notDeduct.getInvNum());

	                String code = deductibleResponse.getResultCode();
	                if ("1".equals(code)) {
	                    Date d = new Date();
	                    //取消不抵扣成功,置为5
	                    notDeduct.setDeductStatus(NotDeductEnum.NOT_DEDUCT_CANCLE_SUCCESS.getCode());//5-取消不抵扣成功
	                    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	                    notDeduct.setResponseTime(formatter.format(d));
	                    notDeduct.setResponseCode(code);
	                    notDeductService.updateByPrimaryKeySelective(notDeduct);
	                    // 更新主表状态
	                    NotDeductRequest notDeductRequest = new NotDeductRequest();
	    				notDeductRequest.setPreDeductFlag(notDeduct.getPreDeductFlag());
	    				notDeductRequest.setInvKind(notDeduct.getInvKind());
	    				notDeductRequest.setInvNum(notDeduct.getInvNum());
	    				notDeductRequest.setBuyerTaxno(notDeduct.getBuyerTaxno());
	    				HashMap<String, Object> preDeductFlagMap = new HashMap();
	    				preDeductFlagMap.put("ids", notDeductRequest.getIds()); 
	    				preDeductFlagMap.put("preDeductFlag", RestFulApiContants.PRE_DEDU_FLAG_INIT); 
	    				int j = notDeductInfoMapper.changePreDeductFlag(preDeductFlagMap);

	                } else if ("0".equals(code) || "6".equals(code)) {
	                    //日志 : 任务执行中
	                    if (logger.isInfoEnabled()) {
	                        logger.info(String.format("executeNotDeductResultRet 发票代码:%s 发票号码:%s  taskno:%s任务执行中", notDeduct.getInvKind(), notDeduct.getInvNum(), notDeduct.getConfirmNoDeductTaskNo()));
	                    }
	                } else {
	                    notDeduct.setDeductStatus(NotDeductEnum.NOT_DEDUCT_SUCCESS.getCode());//2.不抵扣成功
	                    notDeduct.setResponseCode(code);
	                    notDeductService.updateByPrimaryKeySelective(notDeduct);
	                }
	            }
	        } catch (Exception e) {
				logger.error("取消不抵扣定时任务失败:{}",e.getMessage());
			} 
		    finally {
	            latch.countDown();
	        }

	        return new AsyncResult<>("executeNotDeductResultRet  accomplished!");
	}
}
发布了68 篇原创文章 · 获赞 5 · 访问量 9803

猜你喜欢

转载自blog.csdn.net/weixin_44407691/article/details/103541352
今日推荐