NutzCN Logo
问答 nutz结合quartz的问题
发布于 2669天前 作者 qq_95b3862e 4021 次浏览 复制 上一个帖子 下一个帖子
标签: quartz

将定时任务持久化后,有时出现定时任务关不掉的问题:就是我已经关闭了我的持久化对象,并且对象的状态显示关闭,但是我的定时任务没有停止。求大神分析是哪里出错了呢?

12 回复

对象状态显示关闭?通过啥做的?上代码

@wendal 这是service类

package com.zdl.biz.service.sys;

import java.text.ParseException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.nutz.dao.Cnd;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.quartz.CronExpression;
import org.quartz.JobDataMap;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;

import com.zdl.biz.bean.sys.Quartz;
import com.zdl.biz.service.BaseService;
import com.zdl.biz.util.Res;
import com.zdl.biz.util.quartz.Quartzs;

@IocBean(fields = "dao")
public class QuartzService extends BaseService<Quartz> {

	@Inject
	private Scheduler scheduler;

	/**
	 * 任务初始化
	 * 
	 */
	public void init() {
		List<Quartz> quartzs = dao().query(Quartz.class, Cnd.where("state", "=", "1"));
		for (int i = 0; i < quartzs.size(); i++) {
			add(quartzs.get(i));
		}
	}

	/**
	 * 新建任务
	 * 
	 * @param quartz
	 */
	public void add(Quartz quartz) {
		try {
			Class<?> klass = Class.forName(quartz.getClassName());
			JobKey jobKey = quartz.getJobKey();
			Trigger trigger = quartz.getTrigger();
			Set<Trigger> triggers = new HashSet<Trigger>();
			triggers.add(trigger);
			NutMap tmp = null;
			if (!Strings.isBlank(quartz.getDataMap()))
				tmp = Json.fromJson(NutMap.class, quartz.getDataMap());
			JobDataMap data = tmp == null ? new JobDataMap() : new JobDataMap(tmp);
			scheduler.scheduleJob(Quartzs.makeJob(jobKey, klass, data), triggers, true);
		} catch (ClassNotFoundException e) {
			throw Lang.wrapThrow(e);
		} catch (SchedulerException e) {
			throw Lang.wrapThrow(e);
		}
	}

	/**
	 * 新建任务对象
	 * 
	 * @param quartz
	 * @return
	 * @throws ParseException
	 */
	public Res addObj(Quartz quartz) throws ParseException {
		if (Lang.isEmpty(quartz)) {
			return new Res(false, "参数异常");
		} else if (CronExpression.isValidExpression(quartz.getCron())) {
			dao().insert(quartz);
			if ("1".equals(quartz.getState())) {
				add(quartz);
				return new Res(true, "新建对象成功,任务开启");
			} else {
				return new Res(true, "新建对象成功,任务关闭");
			}
		} else {
			return new Res(false, "新建对象失敗,Cron表达式错误");
		}
	}

	/**
	 * 删除任务
	 * 
	 * @param quartz
	 * @return
	 */
	public boolean delete(Quartz quartz) {
		return delete(quartz.getJobKey());
	}

	/**
	 * 删任务
	 * 
	 * @param jobKey
	 * @return
	 */
	public boolean delete(JobKey jobKey) {
		try {
			if (scheduler.checkExists(jobKey))
				return scheduler.deleteJob(jobKey);
			return false;
		} catch (SchedulerException e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 删除任务对象
	 * 
	 * @param ids
	 * @return
	 */
	public Res delObj(Long[] ids) {
		if (Lang.isEmpty(ids)) {
			return new Res(false, "请选择需要删除的定时任务");
		} else {
			Integer count = 0;
			for (Long id : ids) {
				Quartz quartz = fetch(id);
				if (Lang.isEmpty(quartz)) {
					continue;
				}
				if ("1".equals(quartz.getState())) {
					delete(quartz);
				}
				delete(id);
				count++;
			}
			return new Res(true, "成功删除" + count + "条定时任务");
		}
	}

	/**
	 * 编辑任务对象
	 * 
	 * @param quartz
	 * @param id
	 * @return
	 */
	public Res edit(Quartz quartz, Long id) {
		if (Lang.isEmpty(quartz)) {
			return new Res(false, "参数异常");
		} else if (Lang.isEmpty(id)) {
			return new Res(false, "请选择需要编辑的任务");
		} else {
			Quartz oldQuartz = fetch(id);
			if (Lang.isEmpty(oldQuartz)) {
				return new Res(false, "定时任务对象不存在或已被删除");
			} else {
				if (!CronExpression.isValidExpression(quartz.getCron())) {
					return new Res(false, "编辑失败,Cron表达式不正确");
				}
				delete(oldQuartz);
				oldQuartz.setClassName(quartz.getClassName());
				oldQuartz.setJobName(quartz.getJobName());
				oldQuartz.setCron(quartz.getCron());
				oldQuartz.setComment(quartz.getComment());
				oldQuartz.setDataMap(quartz.getDataMap());
				oldQuartz.setState(quartz.getState());
				dao().update(oldQuartz);
				if ("1".equals(oldQuartz.getState())) {
					add(quartz);
				}
				return new Res(true, "定时任务[" + oldQuartz.getJobName() + "] 编辑成功");

			}
		}
	}

	/**
	 * 开启任务
	 * 
	 * @param ids
	 * @return
	 */
	public Res star(Long[] ids) {
		if (Lang.isEmpty(ids)) {
			return new Res(false, "请选择需要开启的定时任务");
		} else {
			Integer count = 0;
			for (Long id : ids) {
				Quartz quartz = fetch(id);
				if (Lang.isEmpty(quartz)) {
					continue;
				}
				if ("0".equals(quartz.getState())) {
					add(quartz);
					quartz.setState("1");
					dao().update(quartz);
					count++;
				} else if ("1".equals(quartz.getState())) {
					add(quartz);
					count++;
				}

			}
			return new Res(true, "成功开启" + count + "条定时任务");
		}
	}

	/**
	 * 关闭任务
	 * 
	 * @param ids
	 * @return
	 */
	public Res close(Long[] ids) {
		if (Lang.isEmpty(ids)) {
			return new Res(false, "请选择需要关闭的定时任务");
		} else {
			Integer count = 0;
			for (Long id : ids) {
				Quartz quartz = fetch(id);
				if (Lang.isEmpty(quartz)) {
					continue;
				}
				if ("1".equals(quartz.getState())) {
					delete(quartz);
					quartz.setState("0");
					dao().update(quartz);
					count++;
				}
			}
			return new Res(true, "成功关闭" + count + "条定时任务");
		}
	}
}

@wendal
package com.zdl.biz.bean.sys;

import java.util.Date;

import org.nutz.dao.entity.annotation.Column;
import org.nutz.dao.entity.annotation.Comment;
import org.nutz.dao.entity.annotation.Id;
import org.nutz.dao.entity.annotation.Table;
import org.nutz.json.Json;
import org.nutz.json.JsonFormat;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Trigger;
import org.quartz.TriggerKey;

import com.zdl.biz.util.quartz.Quartzs;

import lombok.Data;

@Data
@Table("t_sys_quartz")
public class Quartz {

@Id
private int id;

@Column("job_name")
private String jobName;

@Column("job_group")
private String jobGroup;

@Column
private String cron;

@Column("class_name")
private String className;

@Column("data_map")
private String dataMap;

@Column("comment")
private String comment;

@Column("state")
private String state;

@Column("type")
private String type;

@Comment("触发时间")
@Column("star_time")
private Date starTime;

@Comment("结束时间")
@Column("end_time")
private Date endTime;

public Quartz() {}

public Quartz(JobKey jobKey, Trigger trigger, JobDetail jobDetail) {
    setJobKey(jobKey);
    setTrigger(trigger);
    className = jobDetail.getJobClass().getName();
    dataMap = Json.toJson(jobDetail.getJobDataMap(), JsonFormat.compact());
}

public void setJobKey(JobKey jobKey) {
    setJobName(jobKey.getName());
    setJobGroup(jobKey.getGroup());
}

public JobKey getJobKey() {
    return JobKey.jobKey(jobName, String.valueOf(id));
}


public Trigger getTrigger() {
    return Quartzs.makeCronTrigger(jobName, String.valueOf(id), cron);
}

public void setTrigger(Trigger trigger) {
    cron = ((CronTrigger)trigger).getCronExpression();
}

public TriggerKey getTriggerKey() {
    return new TriggerKey(jobName, jobGroup);
}

}

@wendal
一般普通的增删该查都正确的,但是有时候我操作快了,就会出现任务关不掉的错误

调用的是close方法?

close方法里面,continue要打日志,执行deletef方法要判断是否成功.

找到原因了?

@wendal 是的我都加了对delete的判断后发现是编辑那边逻辑错了

@qq_95b3862e 你的那个res类和quartzs封装类能给我借鉴一下么?

貌似是他公司内部的封装, 要不你试试QuartzManager?

添加回复
请先登陆
回到顶部