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

Quartz 3.x切换至AdoJobStore后Trigger持续处于WAITING状态求助

Quartz 3.x 使用AdoJobStore.JobStoreTX时Trigger一直处于WAITING状态的排查方案

核心问题:调度器被提前关闭

你的代码中存在一个致命逻辑错误:在调用scheduler.Start()后立刻执行了scheduler.Shutdown(waitForJobsToComplete:true),导致调度器刚启动就进入关闭流程。

RAMJobStore是内存级存储,任务触发速度极快,可能在关闭前完成执行;但AdoJobStore需要先将任务、触发器持久化到数据库,这个过程有延迟,调度器还没来得及触发任务就被终止,最终Trigger一直停留在WAITING状态。

配置项检查

  1. Quartz表结构初始化
    确认SQL Server中已通过Quartz官方提供的SQL Server建表脚本创建了所有QRTZ_前缀的表,且当前数据库用户拥有读写这些表的权限。

  2. 表前缀配置
    检查quartz.jobStore.tablePrefix的值db_quartz.QRTZ_:其中db_quartz是否是你实际使用的Schema名称(SQL Server默认Schema为dbo),如果Schema不匹配,Quartz会找不到对应表。

  3. 锁处理器配置
    对于SQL Server,推荐将quartz.jobStore.lockHandler.type改为Quartz.Impl.AdoJobStore.StdRowLockSemaphore, Quartz,UpdateLockRowSemaphore在部分SQL Server环境下可能引发锁竞争问题,导致任务无法正常触发。

  4. 数据源连接验证
    确认AnvilPropertyString对应的连接字符串能正常连接到SQL Server,且连接用户拥有足够的数据库操作权限。

  5. JobDataMap类型检查
    由于quartz.jobStore.useProperties设为true,确保JobDataMap中仅存储字符串、数值等简单可序列化类型,你的代码中UsingJobData("NextJobName", "SendMonthlyInvoices")符合要求,但要保证Job类本身没有不可序列化的属性。

代码逻辑优化

  1. 移除即时Shutdown调用
    调度器需要保持运行状态才能触发任务:

    • 如果是控制台程序,可在scheduler.Start()后添加Console.ReadLine()阻塞主线程;
    • 如果是Web应用,需将调度器托管在后台服务中,避免提前关闭。
  2. 修正Job存在性检查逻辑
    当前代码中检查job3存在就删除job1的逻辑不合理,改为检查目标Job本身:

    bool checkWhetherJobExists = await scheduler.CheckExists(new JobKey("job1", "group1"));
    if (checkWhetherJobExists)
    {
        await scheduler.DeleteJob(new JobKey("job1", "group1"));
    }
    
  3. 确认Job类实现
    确保MonthlyInvoicing和SendMonthlyInvoices正确实现IJob接口,且Execute方法无未捕获异常:

    public class MonthlyInvoicing : IJob
    {
        public async Task Execute(IJobExecutionContext context)
        {
            // 任务业务逻辑
            await Task.CompletedTask;
        }
    }
    
  4. 调整任务链监听器添加时机
    将JobChainingJobListener的添加放在Job注册之后,避免链接触发失效:

    await scheduler.ScheduleJob(job, trigger);
    await scheduler.AddJob(job2, true);
    
    JobChainingJobListener jobchain = new JobChainingJobListener("MyJobListener");
    jobchain.AddJobChainLink(new JobKey("job1", "group1"), new JobKey("job3", "group1"));
    scheduler.ListenerManager.AddJobListener(jobchain);
    

内容的提问来源于stack exchange,提问作者Samuel Kamau

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 22:46:05