Is it possible to Kill a current running Quartz Jo

2019-02-12 14:35发布

问题:

i remember that we cannot kill the current running Quartz Job but we can interrupt and have a boolean check wherever is necessary whether we need to proceed further with the subsequent operations or not.

Even when we implement the InterruptableJob and call the scheduler.interrupt to interrupt the Job, the current executed job will be still running in the server.

Ex:

  1. A named SQL query has been triggered by the job via Hibernate which takes a long time
  2. A call has been made to a third party server where the third party server takes a long time to respond

http://neopatel.blogspot.in/2011/05/quartz-stop-job.html http://forums.terracotta.org/forums/posts/list/3191.page

Could someone corrects my understanding and explain me how we can kill or stop the "currently" executing Job ?

Thanks, Kathir

回答1:

As you told, there is no way to interrupt "brutally" a job in quartz, neither in JAVA.

You can encapsulate your job's logic in a separate Thread and run it with the ExecutorService.

Take a look to this example: https://stackoverflow.com/a/2275596/1517816

Assume your QuartzJob is the Test class and move your business logic in the Task class.

Hope it helps



回答2:

you can create new abstract class called JobBase for example that implements IJob interface and insert abstract method: public abstract void ExecuteJob(IJobExecutionContext context);

On JobBase you can implements method Execute like this

public abstract class JobBase : IJob,IInterruptableJob
{
     private Thread currentThread;
     private ILog logger;
     public JobBase(ILog logger)
     {
        this.logger=logger;
     }
        public void Execute(IJobExecutionContext context)
        {

            var thread = new Thread(()=> 
            {
                try
                {
                    this.ExecuteJob(context);
                }
                catch(Exception ex)
                {
                    this.logger.ErrorFormat("Unhandled exception {0}",ex.ToString());

                }
            });

            thread.Start();
            this.currentThread = thread;
            this.currentThread.Join();  
        }
        public abstract void ExecuteJob(IJobExecutionContext context);

        public void Interrupt()
        {   
            currentThread.Abort();
        }
}

Each Job will implements JobExecute method.

  public class TestJob :JobBase
{
    private ILog logger;
    public TeJob(ILog logger):base(logger)
    {
    }

    public override ExecuteJob(IJobExecutionContext context)
    {
    }
}

Assumes that use some factory for creating a Job

For Stopping a Job you will call method scheduler.Interrupt(new JobKey(jobName));



回答3:

I don't know why nobody mentioned this, or maybe this was not available at the time the question was asked.

There is a method called shutdown for a Scheduler instance.

 SchedulerFactory factory = new StdSchedulerFactor();
 Scheduler scheduler = factory.getScheduler();

The above is used to start a job like

  scheduler.start();

Use a flag or something to know when to stop the job from running. Then use

 scheduler.shutdown();

How I implemented my requirement:

 if(flag==true)
{
    scheduler.start();
    scheduler.scheduleJob(jobDetail, simpleTrigger);
}
else if(flag==false)
{
    scheduler.shutdown();
}

Where jobDetail and simpleTrigger are self explanatory.

Hope it helps. :)