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);
                }
            }
        }
    }    
        

问题是:每次触发定时任务,成员变量没有重新初始化,沿用了上次任务赋的值,怎么会这样呢?

猜你喜欢

转载自blog.csdn.net/u014266077/article/details/80767630