在服务器关闭后如何重新启动动态创建的Quartz作业 [英] How to start again Quartz jobs that are created dynamically after a server shutdown

查看:649
本文介绍了在服务器关闭后如何重新启动动态创建的Quartz作业的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是Spring MVC 4.2.5.RELEASE和石英2.2.1石英作业2.2.1

I'm using spring mvc 4.2.5.RELEASE and quartz 2.2.1 quartz-jobs 2.2.1

当用户输入名称和石英作业的cron表达式,然后创建这样的作业

I have a user interface when the user inputs the name and the cron expression of a quartz job, and then I create the job like this

SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();

schedFact.getScheduler().getContext().put("externalInstanceEstatus", myObject);
Scheduler sched = schedFact.getScheduler();
sched.start();

JobDetail job = null;
job = newJob(MyTask.class)
.withIdentity((String) String.valueOf(myUniqueId), "group1")
.build();

Trigger triggerCron = TriggerBuilder
.newTrigger()
.withIdentity(String.valueOf(myUniqueId), "group1")
.withSchedule(
    CronScheduleBuilder.cronSchedule(myObject.getExpresionCron()))
.build();

sched.scheduleJob(job, triggerCron);

用户每次使用该界面时,他都可以创建作业,但该工作正常
,但是当我关闭服务器,我所有的工作都丢失了。我通过将Job名称和cron表达式保存在数据库中来解决此问题,并创建了一种从该表中获取所有记录的方法,然后像这样重新创建Jobs

Everytime that the user goes that interface he can create a job this works fine but when I turn off the server all of my Jobs are lost. I solved this by saving the Job name and cron expression in a database and I created a method that fetch all the records from that table and I re-create the Jobs like this

public void reCreateJobs() {

        ArrayList<MyJob> listOfJobs = searchAllJobsInDB();

        SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();
        Scheduler sched = schedFact.getScheduler();

        //I loop the lsit and I delete all the jobs in the scheduler just in case
        for (MyJob myJob : listOfJobs) {
            for (String group : sched.getJobGroupNames()) {
                for (JobKey jobKey : sched.getJobKeys((GroupMatcher<JobKey>) groupEquals(group))) {
                    if (jobKey.getName().equals(String.valueOf(myJob.getIdMyJob()))) {
                        sched.deleteJob(jobKey);
                    }
                }
            }
        }

        sched.start();

        //THIS IS WHERE I CREATE ALL THE JOBS AGAIN
        for (MyJob myJob : listOfJobs) {

            JobDetail job = newJob(TareaImprimir.class)
                    .withIdentity((String) String.valueOf(myJob.getIdMyJob()), "group1")
                    .build();

            JobDetail job = null;

            Trigger triggerCron = TriggerBuilder
                    .newTrigger()
                    .withIdentity(String.valueOf(myJob.getIdMyJob()), "group1")
                    .withSchedule(
                            CronScheduleBuilder.cronSchedule(myJob.getExpresionCron()))
                    .build();

            sched.scheduleJob(job, triggerCron);
        }
    }

这也很好,我可以再次创建Jobs,他们运行得很好,

This also works fine I can create the Jobs again and they run fine,

我的问题是我需要将值传递给Task Class,但我不知道如何传递它,我知道如何传递它当我第一次像这样创建作业

My problem is that I need to pass a value to the Task Class and I don't know how to pass it, I know how to pass it when I create the job for the first time like this

schedFact.getScheduler().getContext().put("externalInstance", myObject);

然后在我的任务类中得到它

and then I get it in my task Class like this

 SchedulerContext schedulerContext = null;
    try {
        schedulerContext = context.getScheduler().getContext();

    } catch (SchedulerException ex) {
        ex.printStackTrace();
    }
    MyObject externalInstance
            = (MyObject) schedulerContext.get("externalInstance");

我的问题是在重新创建作业时我不知道该怎么做我的方法 reCreateJobs()从数据库中获取它们

My Problem is that I don't know how to do this when I'm recreating the Jobs in my method reCreateJobs() where I get them from the DataBase

如何在方法中设置externalInstance reCreateJobs()或每个作业如何将该值传递给该循环内的MyTask类

How can I set that externalInstance inside my method reCreateJobs() for every Job or How can I pass that value to the MyTask class inside that loop

这是我的任务类

public class MyTask implements Job {

@Autowired
SomeDAO someDAO;

public void execute(JobExecutionContext context)
        throws JobExecutionException {

    SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);

    SchedulerContext schedulerContext = null;
    try {
        schedulerContext = context.getScheduler().getContext();
    } catch (SchedulerException ex) {
        Logger.getLogger(MyTask.class.getName()).log(Level.SEVERE, null, ex);
    }
    MyObject externalInstance
            = (MyObject) schedulerContext.get("externalInstance");

    someDAO.doSomething(externalInstance.getSomething());
}

}

推荐答案

因为我无法评论,所以将其添加为答案

您不使用 JDBC-JobStoreTX

JDBCJobStore用于在关系数据库中存储调度信息(作业,触发器和日历)。实际上,您可以根据需要的事务行为在两个单独的JDBCJobStore类之间进行选择。

JDBCJobStore is used to store scheduling information (job, triggers and calendars) within a relational database. There are actually two seperate JDBCJobStore classes that you can select between, depending on the transactional behaviour you need.

JobStoreTX通过在对象上调用commit()(或rollback())来管理所有事务本身。每个操作(例如添加作业)之后的数据库连接。如果在独立应用程序中使用Quartz,或者在servlet容器中使用Quartz(如果应用程序未使用JTA事务),则JDBCJobStore是合适的。

JobStoreTX manages all transactions itself by calling commit() (or rollback()) on the database connection after every action (such as the addition of a job). JDBCJobStore is appropriate if you are using Quartz in a stand-alone application, or within a servlet container if the application is not using JTA transactions.

您可以将要保存的数据持久保存到 JobDataMap

That way you can persist the data you want to JobDataMap


保留作业实例的状态信息。

Holds state information for Job instances.

JobDataMap实例在将作业添加到调度程序后存储一次。在每次执行@PersistJobDataAfterExecution注释的作业后,它们也会重新持久化。

JobDataMap instances are stored once when the Job is added to a scheduler. They are also re-persisted after every execution of jobs annotated with @PersistJobDataAfterExecution.

JobDataMap实例也可以与触发器一起存储。如果您有一个Job存储在调度程序中以供多个触发器定期/重复使用,但是对于每个独立的触发器,您想为Job提供不同的数据输入,则这很有用。

JobDataMap instances can also be stored with a Trigger. This can be useful in the case where you have a Job that is stored in the scheduler for regular/repeated use by multiple Triggers, yet with each independent triggering, you want to supply the Job with different data inputs.

在执行时传递给Job的JobExecutionContext还包含一个便利的JobDataMap,它是将触发器的JobDataMap(如果有)的内容合并到Job的JobDataMap(如果有的话)上的结果。

The JobExecutionContext passed to a Job at execution time also contains a convenience JobDataMap that is the result of merging the contents of the trigger's JobDataMap (if any) over the Job's JobDataMap (if any).

这篇关于在服务器关闭后如何重新启动动态创建的Quartz作业的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆