Quartz 1.7.3作业遇异常重触发问题求助:最多5次重触发失效
Hey there, let’s tackle this retry issue you’re facing with Quartz 1.7.3. I’ve run into exactly this kind of quirk with older Quartz versions before, so let’s break down the most likely causes and fixes step by step.
First, let’s get clear: Quartz 1.7.3 doesn’t have built-in "max retry on failure" out of the box for arbitrary exceptions. If your manual retry calls aren’t working, it’s probably due to one of these common mistakes:
1. You’re not persisting retry counts correctly
Quartz 1.7.3 treats regular Job classes differently from StatefulJob when it comes to JobDataMap persistence:
- Regular
Job: The JobDataMap resets to its initial state every execution—any changes you make won’t stick between retries. StatefulJob: The JobDataMap is persisted between executions, so you can track retry counts reliably.
Fix: Switch to StatefulJob
Update your job class to implement StatefulJob instead of Job:
public class MyRetryableJob implements StatefulJob { private static final int MAX_RETRIES = 5; private static final String RETRY_COUNT_KEY = "retryCount"; @Override public void execute(JobExecutionContext context) throws JobExecutionException { JobDataMap jobData = context.getJobDetail().getJobDataMap(); int currentRetryCount = jobData.getInt(RETRY_COUNT_KEY); try { // Your core job logic here runJobTask(); // Reset retry count if job succeeds jobData.put(RETRY_COUNT_KEY, 0); } catch (Exception e) { currentRetryCount++; if (currentRetryCount <= MAX_RETRIES) { // Update retry count in persisted JobDataMap jobData.put(RETRY_COUNT_KEY, currentRetryCount); try { // Schedule an immediate retry (add delay if needed) Trigger retryTrigger = TriggerUtils.makeImmediateTrigger( "retry-trigger-" + currentRetryCount, 1, 0 ); retryTrigger.setJobName(context.getJobDetail().getName()); retryTrigger.setJobGroup(context.getJobDetail().getGroup()); // Use the scheduler from the current execution context (critical!) context.getScheduler().scheduleJob(retryTrigger); } catch (SchedulerException se) { throw new JobExecutionException("Failed to schedule retry attempt " + currentRetryCount, se); } } else { // Max retries hit—fail the job permanently throw new JobExecutionException( "Job failed after " + MAX_RETRIES + " retries", e, false // Don't refire immediately ); } } } private void runJobTask() throws Exception { // Your business logic that might throw exceptions } }
2. Your JobDetail isn’t marked as durable
If your JobDetail isn’t durable, Quartz might discard it when there are no active triggers, losing your retry count data. Make sure to set durability to true when creating the JobDetail:
JobDetail jobDetail = new JobDetail( "my-retryable-job", "job-group", MyRetryableJob.class ); jobDetail.setDurability(true); // Critical for persistence between retries
3. You’re using the wrong method to trigger retries
Avoid using JobExecutionException(e, true) (the refireImmediately flag)—this tells Quartz to retry immediately, but it doesn’t track retry counts and will loop infinitely if the error persists. Instead, explicitly schedule a new trigger as shown in the code above, which gives you full control over retry limits.
Quick Troubleshooting Checks
- Add debug logs to print
currentRetryCounton each execution to confirm it’s incrementing correctly. - Verify that your scheduler instance (from
context.getScheduler()) is the same one managing the job—using a separate scheduler instance can cause retries to fail silently. - Ensure your Quartz job store is configured to persist job data (e.g., using JDBCJobStore instead of RAMJobStore if you need persistence across restarts).
内容的提问来源于stack exchange,提问作者skp

