{"record":{"id":"54ac9018cb26ff90","repo":"elunez/eladmin","slug":"error-54ac90","errorCode":null,"errorMessage":"更新定时任务失败","messagePattern":"更新定时任务失败","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"eladmin-system/src/main/java/me/zhengjie/modules/quartz/utils/QuartzManage.java","lineNumber":102,"sourceCode":"            // 如果不存在则创建一个定时任务\n            if(trigger == null){\n                addJob(quartzJob);\n                trigger = (CronTrigger) scheduler.getTrigger(triggerKey);\n            }\n            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(quartzJob.getCronExpression());\n            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();\n            //重置启动时间\n            ((CronTriggerImpl)trigger).setStartTime(new Date());\n            trigger.getJobDataMap().put(QuartzJob.JOB_KEY,quartzJob);\n\n            scheduler.rescheduleJob(triggerKey, trigger);\n            // 暂停任务\n            if (quartzJob.getIsPause()) {\n                pauseJob(quartzJob);\n            }\n        } catch (Exception e){\n            log.error(\"更新定时任务失败\", e);\n            throw new BadRequestException(\"更新定时任务失败\");\n        }\n\n    }\n\n    /**\n     * 删除一个job\n     * @param quartzJob /\n     */\n    public void deleteJob(QuartzJob quartzJob){\n        try {\n            JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId());\n            scheduler.pauseJob(jobKey);\n            scheduler.deleteJob(jobKey);\n        } catch (Exception e){\n            log.error(\"删除定时任务失败\", e);\n            throw new BadRequestException(\"删除定时任务失败\");\n        }\n    }","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/elunez/eladmin/blob/55fbf705956949697dbd68bf9003776609d3d029/eladmin-system/src/main/java/me/zhengjie/modules/quartz/utils/QuartzManage.java#L84-L120","documentation":"QuartzManage.updateJobCron rebuilds the CronTrigger for a job and calls scheduler.rescheduleJob(triggerKey, trigger); any exception in that flow (missing trigger, schedule build failure, reschedule failure) is logged and rethrown as BadRequestException '更新定时任务失败'. Because callers are @Transactional, the already-saved job row update rolls back.","triggerScenarios":"PUT /api/quartz/jobs where the trigger JOB_NAME+id does not exist in the scheduler (e.g. job was created but scheduling previously failed, or scheduler state was wiped while DB rows remain), or the new cron fails trigger-level validation that the earlier CronExpression.isValidExpression check passed.","commonSituations":"Database restored from backup while Quartz's RAMJobStore lost triggers — DB has the job but the scheduler does not, so rescheduleJob throws 'Trigger does not exist'; mixing persistent store and memory store between restarts.","solutions":["Check the logged stack trace for the true exception (commonly ObjectDoesNotExistException for the trigger key).","If the trigger is missing, recreate the job via the UI (delete + re-add) so addJob registers a fresh trigger, or call the resume/run path which lazily calls addJob when trigger == null.","Keep Quartz job store and the business DB consistent — when wiping quartz tables, also clear quartz_job rows."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// detect trigger-drift before updating\nTriggerKey tk = TriggerKey.triggerKey(\"JOB_NAME\" + job.getId());\nif (scheduler.getTrigger(tk) == null) {\n    // recreate instead of reschedule\n    quartzManage.addJob(job);\n}","typeGuard":null,"tryCatchPattern":"try { quartzJobService.update(job); } catch (BadRequestException e) { if (\"更新定时任务失败\".equals(e.getMessage())) { log.error(\"reschedule failed\", e); quartzManage.addJob(job); // rebuild trigger } else throw e; }","preventionTips":["Treat DB and scheduler store as one unit — restore/reset them together.","Expose a health check listing quartz_job rows lacking a live trigger.","Prefer the lazy-recreate paths (resume/run) when triggers are known to drift."],"tags":["quartz","scheduler","state-mismatch","transactions"],"backgroundTag":null,"analyzedSha":"55fbf705956949697dbd68bf9003776609d3d029","analyzedAt":"2026-08-14T11:56:12.758Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}