Tuesday 13 March 2012

JDBCJobStore in Quartz Scheduler

JDBCJobStore is a way of maintaining the quartz job details over a database via the JDBC. While the use of RAMJobStore indicates volatile storage of the quartz job details, a JDBCJobStore ensures that the information on the quartz jobs, triggers, calendars etc are available any time in case the system has a downtime and then can be rescheduled once the system is up.
A JDBCJobStore requires some database tables to be present in the data source defined for use of quartz. The sql queries for creating and populating the required tables is available under the docs/dbTables folder of the quartz distribution. The following example uses the MySQL database to schedule a job using the JDBCJobStore.
The file quartz.properties is used by the program to define the quartz properties -
Sample Program – file quartz.properties

#Skip Update Check
#Quartz contains an "update check" feature that connects to a server to
#check if there is a new version of Quartz available
org.quartz.scheduler.skipUpdateCheck: true

org.quartz.scheduler.instanceName =OZS_SCHEDULAR
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 4
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
org.quartz.threadPool.threadPriority = 5


#specify the jobstore used
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties = false

#specify the TerracottaJobStore
#org.quartz.jobStore.class = org.terracotta.quartz.TerracottaJobStore
#org.quartz.jobStore.tcConfigUrl = localhost:9510


#The datasource for the jobstore that is to be used
org.quartz.jobStore.dataSource = myDS

#quartz table prefixes in the database
org.quartz.jobStore.tablePrefix = qrtz_
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.isClustered = false

#The details of the datasource specified previously
org.quartz.dataSource.myDS.driver =com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL =jdbc:mysql://localhost:3306/test
org.quartz.dataSource.myDS.user =root
org.quartz.dataSource.myDS.password =
org.quartz.dataSource.myDS.maxConnections = 20

#Clustering
#clustering currently only works with the JDBC-Jobstore (JobStoreTX
#or JobStoreCMT). Features include load-balancing and job fail-over
#(if the JobDetail's "request recovery" flag is set to true). It is important to note that
# When using clustering on separate machines, make sure that their clocks are synchronized
#using some form of time-sync service (clocks must be within a second of each other).
#See http://www.boulder.nist.gov/timefreq/service/its.htm.
# Never fire-up a non-clustered instance against the same set of tables that any
#other instance is running against.
# Each instance in the cluster should use the same copy of the quartz.properties file.

org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000

#Each server must have the same copy of the configuration file.
#auto-generate instance ids.
org.quartz.scheduler.instanceId = AUTO

#Note :
#If a job throws an exception, Quartz will typically immediately
#re-execute it (and it will likely throw the same exception again).
#It's better if the job catches all exception it may encounter, handle them,
#and reschedule itself, or other jobs. to work around the issue.


  MyJob .java
package com.opensourzesupport.schedule.jobs;
 
import org.quartz.Job;

import org.quartz.JobExecutionContext;

import org.quartz.JobExecutionException;


/**

 *

 * @author prasobh

 */


public class MyJob  implements Job{


    @Override

    public void execute(JobExecutionContext jec) throws JobExecutionException {

        System.out.println("executing my my job");

    }   

}



Schedule.java
package com.opensourzesupport.schedule;

import com.opensourzesupport.schedule.jobs.MyJob;
import com.opensourzesupport.schedule.listeners.MyJobListener;
import java.util.Date;

import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerUtils;
import org.quartz.impl.StdSchedulerFactory;

/**
 *
 * @author prasobh
 */
public class Schedular {

    public Schedular() {
        try {
            SchedulerFactory schdFact = new StdSchedulerFactory("quartz.properties");
            Scheduler schd = schdFact.getScheduler();
            schd.start();

            JobDetail jd = new JobDetail("alarmjob", Scheduler.DEFAULT_GROUP, MyJob.class);
            Trigger t = TriggerUtils.makeDailyTrigger("alarmtrigger", 06, 00);
            t.getJobDataMap().put("auth_name", "Vageesh");
            t.setStartTime(new Date());
            schd.addJobListener(new MyJobListener());
            jd.addJobListener("Alarm gone");
            schd.scheduleJob(jd, t);
            schd.start();
            System.out.println(schd.getSchedulerName());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        new Schedular();
    }
}


On successful fire of job, it can be observed that the job details and 
data blob details are updated in the tables of the database
 

Rescheduling Job

Rescheduler.java


package com.opensourzesupport.schedule;


import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;

/**
 *
 * @author prasobh
 */
public class Reschedular {

    public 
Reschedular() {

        String[] triggerGrps;
        String[] triggers;
        try {

            SchedulerFactory sf = new StdSchedulerFactory("quartz.properties");
            Scheduler sd = sf.getScheduler();
            sd.start();
            triggerGrps = sd.getTriggerGroupNames();
            for (String stTriggerGrp : triggerGrps) {
                triggers = sd.getTriggerNames(stTriggerGrp);
                for (String stTrigger : triggers) {
                    Trigger quartzTrigger = sd.getTrigger(stTrigger, stTriggerGrp);
                    System.out.println("Trigger Name : " + stTrigger);
                    System.out.println("Trigger Group Name: " + stTriggerGrp);
                    sd.rescheduleJob(stTrigger, stTriggerGrp, quartzTrigger);
                }
            }
          
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        new Reschedular();
    }
}

 

 

 

3 comments:

  1. Kiến thức của Admin rất hữu ích, thank bạn đã share.
    Xem tại website : Thạch anh vụn

    ReplyDelete
  2. https://vageeshhoskere.wordpress.com/2011/05/09/jdbc-job-store-quartz-scheduler/
    https://vageeshhoskere.wordpress.com/2011/05/09/rescheduling-job-from-jdbcjobstore-quartz-scheduler/

    ReplyDelete