1. 程式人生 > >quartz多次觸發定時任務時成員變數未初始化

quartz多次觸發定時任務時成員變數未初始化

專案中遇到一個問題:每2分鐘觸發一次的定時任務只執行一次!每次啟動專案時,看到做補償處理的定時任務確實被觸發了,但是,定時任務只跑一次,而且,理論上只會取到10條資料,但是卻取到了全部需要補償的資料,讓我很是詫異,於是決定研究一番,後來發現是每次作為起始點的引數被置為最終的id,導致第二次的起始點不是0,所以繼續第一次未取到的資料往後做補償處理了,如果資料足夠多,第三次,第四次......起始點都會是上一次id的最大值,繼續做處理,直到做完一輪,下次定時任務觸發時,由於起始值已經是所有資料id的最大值,所以取不到需要補償的資料,也就不能從頭開始補償了。

package com.weimob.saas.ec.payment.task;
import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import com.weimob.saas.ec.payment.utils.EnvInfoCheckUtil; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.fastjson.JSON; import com.dianping.cat.Cat; import com.dianping.cat.message.Transaction; import com.weimob.saas.ec.common.util.SoaUtil; import com.weimob.saas.ec.payment.constant.PaymentConstant; import com.weimob.saas.ec.payment.dao.PaymentCompensationLogDao;
import com.weimob.saas.ec.payment.model.entity.PaymentCompensationLogEntity; import com.weimob.saas.ec.payment.service.third.MessageThirdService; import com.weimob.saas.ec.soa.utils.SpringBeanUtils; import com.weimob.sendInnerEmail.util.MailUtil; /** * @description 補償處理task * @date 2017年10月1日 上午11:55:52 */ public class PaymentCompensationTask { private static final Logger LOGGER = LoggerFactory.getLogger(PaymentCompensationTask.class); private String runTaskIp; private Integer limitNum; private PaymentCompensationLogDao paymentCompensationLogDao; private MessageThirdService messageThirdService; private Long maxId; private String receiverEmailList; private String receiverPhoneNoList; private Integer sendEmailCountCondition; private Integer sendTextMessageCountCondition; private Integer maxSendEmailTimes; private Integer maxSendTextMessageTimes; /** * 定時任務執行緒是否啟動標誌 */ private static AtomicBoolean isCompensationTaskRunning = new AtomicBoolean(false); public void handlePaymentCompensatioin() { long startTime = System.currentTimeMillis(); String catStatus = Transaction.SUCCESS; String catTypeName = ""; //1. 判斷ip, 當前機器ip是否是配置的ip if (!SoaUtil.getLocalIp().equals(runTaskIp)) { LOGGER.error("payment compensation server ip " + (SoaUtil.getLocalIp() + " is not as same as " + runTaskIp)); return; } //判斷定時任務的執行緒是否結束 if (isCompensationTaskRunning.compareAndSet(false, true)) { try { //2. 從資料庫分頁取出需要補償的記錄 List<PaymentCompensationLogEntity> logEntityList = null; try { logEntityList = paymentCompensationLogDao.queryPaymentCompensationLogList(maxId, limitNum); } catch (Exception e) { LOGGER.error("fail to query payment compensation log list", e); catStatus = Transaction.FAIL; } //3. 遍歷補償日誌,反射呼叫相對應的方法 if (!CollectionUtils.isEmpty(logEntityList)) { for (PaymentCompensationLogEntity logEntity : logEntityList) { //3.1 通過spring容器找出service maxId = logEntity.getId(); boolean isPushSuccess = true; String serviceName = logEntity.getServiceName(); String methodName = logEntity.getMethodName(); String parameterInput = logEntity.getParameterInput(); Object serviceBean = SpringBeanUtils.getBean(serviceName); if (null == serviceBean) { continue; } List<String> paramList = new ArrayList<String>(); //3.2 遍歷出bean下面的方法 boolean isInvoked = false; for (Class<?> beanInterface : serviceBean.getClass().getInterfaces()) { long executeStartTime = System.currentTimeMillis(); try { for (Method method : beanInterface.getMethods()) { if (methodName.equals(method.getName())) { Type[] types = method.getGenericParameterTypes(); List<Object> params = new ArrayList<Object>(); if (types.length == 1) { paramList.add(parameterInput); } if (types.length > 1) {// 超過2個引數,將JSON引數轉為List<String>,後續再逐個轉為對應的物件 List<String> tmepList = JSON.parseArray(parameterInput, String.class); paramList.clear(); paramList.addAll(tmepList); } if (types.length == paramList.size()) {// 引數數量必須相同 for (int i = 0; i < types.length; i++) { params.add(JSON.parseObject(paramList.get(i), types[i])); } isInvoked = true; catTypeName = serviceName + "." + methodName; method.invoke(serviceBean, params.toArray()); break; } } } } catch (Exception e) { LOGGER.error("fail to invoke ", e); catStatus = Transaction.FAIL; isPushSuccess = false; } finally { try { Cat.logTransaction(PaymentConstant.CAT_TYPE_TASK, catTypeName, executeStartTime, catStatus); } catch (Exception e) { LOGGER.error("fail to cat ", e); } } if (isInvoked) { break; } } //4. 更新補償日誌的記錄 if (isInvoked) { if (isPushSuccess) { logEntity.setIsSuccess(PaymentConstant.COMPENSATION_PUSH_SUCCESS); } else { logEntity.setIsSuccess(PaymentConstant.COMPENSATION_PUSH_FAILED); } logEntity.setPushCount(logEntity.getPushCount() + 1); sendEmail(logEntity); sendTextMessage(logEntity, catTypeName); } updateCompensationLogStatus(logEntity); } } } catch (Exception e) { LOGGER.error("fail to execute update compensation", e); catStatus = Transaction.FAIL; } finally { isCompensationTaskRunning.compareAndSet(true, false); try { Cat.logTransaction(PaymentConstant.CAT_TYPE_TASK, PaymentConstant.CAT_NAME_COMPENSATION_LOG, startTime, catStatus); } catch (Exception e) { LOGGER.error("fail to cat log", e); } } } }

問題是:每次觸發定時任務,成員變數沒有重新初始化,沿用了上次任務賦的值,怎麼會這樣呢?