Im using quartz.net in a asp.net mvc application.

Trying to configurate it to user ADOStore.

I have created the tables.

NameValueCollection properties = new NameValueCollection();

        properties["quartz.scheduler.instanceName"] = "TestScheduler";
        properties["quartz.scheduler.instanceId"] = "instance_one";
        properties["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz";
        properties["quartz.jobStore.useProperties"] = "true";
        properties["quartz.jobStore.dataSource"] = "default";
        properties["quartz.jobStore.tablePrefix"] = "QRTZ_";
        // if running MS SQL Server we need this
        properties["quartz.jobStore.lockHandler.type"] = "Quartz.Impl.AdoJobStore.UpdateLockRowSemaphore, Quartz";

        properties["quartz.dataSource.default.connectionString"] = "Server=.\\SQLExpress;Database=test;Trusted_Connection=True;";
        properties["quartz.dataSource.default.provider"] = "SqlServer-20";

// StdSchedulerFactory
        this.Initialize(properties);

When running the application im getting errormessages:

A first chance exception of type 'Quartz.ObjectAlreadyExistsException' occurred in Quartz.dll A first chance exception of type 'Quartz.JobPersistenceException' occurred in Quartz.dll A first chance exception of type 'Quartz.JobPersistenceException' occurred in Quartz.dll

When looking in the QRTZ_ tables QRTZ_JOB_DETAILS has one post in it for the job. The other tables is empty.

Any idea whats causing the problem here?

UPDATE:

public class UnitySchedulerFactory : StdSchedulerFactory
{
    private readonly UnityJobFactory unityJobFactory;

    public UnitySchedulerFactory(UnityJobFactory unityJobFactory)
    {
        NameValueCollection properties = new NameValueCollection();

        properties["quartz.scheduler.instanceName"] = "TestScheduler";
        properties["quartz.scheduler.instanceId"] = "instance_one";
        properties["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz";
        properties["quartz.jobStore.useProperties"] = "true";
        properties["quartz.jobStore.dataSource"] = "default";
        properties["quartz.jobStore.tablePrefix"] = "QRTZ_";
        // if running MS SQL Server we need this
        properties["quartz.jobStore.lockHandler.type"] = "Quartz.Impl.AdoJobStore.UpdateLockRowSemaphore, Quartz";

        properties["quartz.dataSource.default.connectionString"] = "Server=.\\SQLExpress;Database=189021;Trusted_Connection=True;";
        properties["quartz.dataSource.default.provider"] = "SqlServer-20";

        this.Initialize(properties);
        this.unityJobFactory = unityJobFactory;
    }

    protected override IScheduler Instantiate(QuartzSchedulerResources rsrcs, QuartzScheduler qs)
    {
        qs.JobFactory = this.unityJobFactory;            
        return base.Instantiate(rsrcs, qs);
    }
}

Global.asax

var scheduler = unityContainer.Resolve<IQuartzScheduler>();
scheduler.Run();

UPDATE 2

Here is a link to the whole quartz solution:

http://1drv.ms/1o0rpg8

Quartz tables is created from following:

https://github.com/MassTransit/MassTransit-Quartz/blob/master/setup_sql_server.sql

Global.asax:

var unityContainer = Infrastructure.Bootstrapper.Initialise();

var scheduler = unityContainer.Resolve<IQuartzScheduler>();
scheduler.Run(); 

The thing I'm trying to do is handle the misfiring with ADOstore so that the system can hanlde a restart or a crash.

有帮助吗?

解决方案

If you're persisting your jobs (as you do) in a database you cannot create them all the time.
You have to check if they exists at the start-up.

Check my answer here for more details.

When Quartz.Net is initialized and you're using AdoJobStore, the scheduler fetches all the jobs/triggers save in the database.

In your IQuartzScheduler.Run() you should check if the job is present:

this.Scheduler.GetJobDetail()

You can use this bit of code to test if it works:

IJobDetail helloJob = null;
ITrigger helloTrigger = null;

helloJob = this.Scheduler.GetJobDetail(new JobKey("HelloJob", "MyGroup"));

if (helloJob == null)
{
    helloJob = JobBuilder.Create<Jobs.HelloJob>()
        .WithIdentity("HelloJob", "MyGroup")
        .RequestRecovery(true)
        // .StoreDurably(true)
        .Build();

    helloTrigger = TriggerBuilder.Create()
         .WithIdentity("HelloTrigger", "MyGroup")
         .StartNow()
         .WithSimpleSchedule(x => x.RepeatForever().WithIntervalInSeconds(20))
         .Build();

    this.Scheduler.ScheduleJob(helloJob, helloTrigger);
}

this.Scheduler.Start();

If you're using the latest Quartz.Net version there seem to be a problem with the database creation script.

I've noticed that the triggers don't fire. I've then created the database using the latest scripts from Quartz.Net repository on GitHub and it works properly.

Check this answer as well. There are few more details on Quartz.Net + AdoJobStore.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top