You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quartz 1.7.3作业遇异常重触发问题求助:最多5次重触发失效

Fixing Quartz 1.7.3 Job Retries on Exception

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 currentRetryCount on 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:48:32