Search code examples
c#.netjobsquartz.net

Quartz.net JobStoreTX Job Save issue


I'm trying to run Quartz.net server for my website maintance tasks. I create Jobs and triggers in my WCF application (hosted on IIS). So they can be stored in database (SQL Server).

Now i can't understand ADO.NET Job Store. Here is my web.config part for Quartz.net:

<configSections>
    <section name="quartz" type="System.Configuration.NameValueSectionHandler" />
</configSections>
<quartz>
    <add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz" />
        <add key="quartz.threadPool.threadCount" value="10" />
        <add key="quartz.threadPool.threadPriority" value="Normal" />
        <add key="quartz.jobStore.misfireThreshold" value="60000" />
        <add key="quartz.jobStore.type" value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz" />
        <add key="quartz.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.**SqlServerDelegate**, Quartz" />
        <add key="quartz.jobStore.tablePrefix" value="QRTZ_" />
        <add key="quartz.jobStore.dataSource" value="ConnectionString" />
        <add key="quartz.dataSource.ConnectionString.connectionString" value="Server=*;Database=*;Uid=*;Pwd=*" />
        <add key="quartz.dataSource.ConnectionString.provider" value="SqlServer-20" />
        <add key="quartz.scheduler.instanceName" value="PaymentService" />

        <add key="quartz.jobStore.useProperties" value="true" />
</quartz>

And here is my global.asax:

public class Global : System.Web.HttpApplication
    {
        public static ISchedulerFactory Factory;
        public static IScheduler Scheduler;

        protected void Application_Start(Object sender, EventArgs e)
        {
            Factory = new StdSchedulerFactory();
            Scheduler = Factory.GetScheduler();

            JobKey JobKey = new JobKey("GetOrderInfoJob", "Project");
            if (Scheduler.CheckExists(JobKey))
                Scheduler.DeleteJob(JobKey);

            IJobDetail job = JobBuilder.Create<PaymentServiceLogic>()
                .WithIdentity(JobKey)
                .StoreDurably()
                .RequestRecovery()
                .Build();

            TriggerKey triggerKey = new TriggerKey("GetOrderInfoTrigger", "Project");

            TriggerBuilder tb = TriggerBuilder.Create();
            tb.WithIdentity(triggerKey );
            tb.WithSimpleSchedule(a => a.WithIntervalInMinutes(1));
            tb.StartNow();
            tb.ForJob(job);
            ITrigger trigger = tb.Build();
            Scheduler.ScheduleJob(trigger);

            Scheduler.Start();
        }
}

Once i've started WCF service on localhost, QRTZ_JOB_DETAILS table in SQL Server for jobs had 1 entry, but no triggers. I've tested this code a couple times and now no jobs are storing and therefore i have this exception: Couldn't store trigger job: The job referenced by the trigger does not exist.

Is there some bug with job's building or AdoJobStore?

And the second question is about how to do correct shutdown in global.asax. Now i've decided this method:

protected void Application_End(object sender, EventArgs e)
        {
            ICollection<IScheduler> all = Factory.AllSchedulers;
            foreach (IScheduler item in all)
            {
                item.Shutdown(true);
            }
        }

and implementing my own logging in Application_Error.


Solution

  • Note, sure whether it is a good idea to ask two questions in one, but the answer to your first question is you need to change

    Scheduler.ScheduleJob(trigger);
    

    to

    Scheduler.ScheduleJob(job, trigger);
    

    The former is when the job has previously been added to the scheduler, whereas the latter adds both the job and trigger at the same time.