We have an application which is using Quartz to schedule some job. It uses the JDBCJobstore for persisting job related Meta-Data.
Hitherto it has been using datasource which was defined in quartz.properties. But according to upcoming requirement we are planning to move out the datasource from quartz.properties and provide it as part of SchedulerFactoryBean datasource property.
org.springframework.scheduling.quartz.SchedulerFactoryBean
According the SchedulerFactoryBean documentation:
When using persistent jobs, it is strongly recommended to perform all operations on the Scheduler within Spring-managed (or plain JTA) transactions. Else, database locking will not properly work and might even break
and its datasource property docs says:
It is therefore strongly recommended to perform all operations on the Scheduler within Spring-managed (or plain JTA) transactions. Else, database locking will not properly work and might even break
Well, in my case it is breaking. What exactly the documentation mean by "to perform all operations on the Scheduler within Spring-managed (or plain JTA) transactions".
The datasource we have provided is not being used anywhere else. Quartz.properties look something like this:
org.quartz.scheduler.instanceName = JobScheduler
org.quartz.scheduler.instanceId = pcmlScheduler
org.quartz.plugin.shutdownHook.class=org.quartz.plugins.management.ShutdownHookPlugin
org.quartz.plugin.shutdownHook.cleanShutdown = true
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 2
org.quartz.threadPool.threadPriority = 4
org.quartz.jobStore.misfireThreshold = 5000
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix = QRTZ_
if I can get a context what exactly transaction is refering to I can further zero down on the database lock BreaK:
Failure obtaining db row lock: No row exists in table QRTZ_LOCKS for lock named: TRIGGER_ACCESS [See nested exception: java.sql.SQLException: No row exists in table QRTZ_LOCKS for lock named: TRIGGER_ACCESS]
It is true that QRTZ_LOCKS don't have any row, but it should all be quartz headache to manage that. And it is managing fine, working perfectly when datasource is provided in quartz.properties.
UPDATE: From quartz forum, got a duplicate of this question, where as per suggestion, adding following rows into QRTZ_LOCKS solve the issue.
INSERT INTO QRTZ_LOCKS values('TRIGGER_ACCESS');
INSERT INTO QRTZ_LOCKS values('JOB_ACCESS');
INSERT INTO QRTZ_LOCKS values('CALENDAR_ACCESS');
INSERT INTO QRTZ_LOCKS values('STATE_ACCESS');
INSERT INTO QRTZ_LOCKS values('MISFIRE_ACCESS');
I don't how reliable is this, but it worked. Interesting observation is that when providing datasource as part quary.properties it was not expecting these rows. But providing datasource as part schedulerFactoryBean, it needs these(probably). Ideally, even if it was needed, it should have taken care by quartz itself.
Will NEED some expert comment from quartz insider/user.