I use quartz in spring project. The idea is to create separate job for new income data, that was not delivered successfully to target service.
I tried to manage JobExecutionContext
of triggered job to use same JobDetail
registering it in quartzScheduler
. The idea was to update existing job with different trigger. But issue is quartz tries to create new job persisting it in DB.
org.quartz.ObjectAlreadyExistsException: Unable to store Job : 'digex-caas-securepay.b333e5bf-583f-4643-9ad7-ef4b913001f7', because one already exists with this identification.
at org.quartz.impl.jdbcjobstore.JobStoreSupport.storeJob(JobStoreSupport.java:1113) ~[quartz-2.3.0.jar:na]
at org.quartz.impl.jdbcjobstore.JobStoreSupport$2.executeVoid(JobStoreSupport.java:1067) ~[quartz-2.3.0.jar:na]
at org.quartz.impl.jdbcjobstore.JobStoreSupport$VoidTransactionCallback.execute(JobStoreSupport.java:3765) ~[quartz-2.3.0.jar:na]
at org.quartz.impl.jdbcjobstore.JobStoreSupport$VoidTransactionCallback.execute(JobStoreSupport.java:3763) ~[quartz-2.3.0.jar:na]
at org.quartz.impl.jdbcjobstore.JobStoreCMT.executeInLock(JobStoreCMT.java:245) ~[quartz-2.3.0.jar:na]
at org.quartz.impl.jdbcjobstore.JobStoreSupport.storeJobAndTrigger(JobStoreSupport.java:1063) ~[quartz-2.3.0.jar:na]
at org.quartz.core.QuartzScheduler.scheduleJob(QuartzScheduler.java:855) ~[quartz-2.3.0.jar:na]
at org.quartz.impl.StdScheduler.scheduleJob(StdScheduler.java:249) ~[quartz-2.3.0.jar:na]
at com.incomm.ecomm.services.quartz.OrderQuartzJobScheduler.registerSecurePayPostServiceJob(OrderQuartzJobScheduler.java:59) ~[classes/:na]
scheduler.rescheduleJob(trigger.getKey(), trigger);
- How to manage via quartz job trigger updates
scheduler.rescheduleJob(trigger.getKey(), trigger);
- How to manage via quartz job updates
It is not important any more in case trigger updated.
- How to register exponentially increasing delay time strategy for trigger?
single trigger can be rescheduled with any different time. Time for next execution can be calculated using any implementation of IntervalCalculationStrategy
.
The job and job details can be taken from JobExecutionContext
but not necessary. Trigger can be connected to only one job, so it good enough for quartz specify triggerKey
to be updated:
@Autowired
private Scheduler scheduler;
@Autowired
private IntervalCalculationStrategy intervalCalculation;
public <T extends QuartzJobBean> void registerSecurePayPostServiceJob(
JobExecutionContext firedJobExecutionContext) {
Optional<SimpleTriggerImpl> mutableTrigger =
ofNullable(firedJobExecutionContext)
.map(JobExecutionContext::getTrigger)
.filter(SimpleTriggerImpl.class::isInstance)
.map(SimpleTriggerImpl.class::cast);
try {
if (mutableTrigger.isPresent()) {
SimpleTriggerImpl trigger = mutableTrigger.get();
int nextAttemptNumber = trigger.getTimesTriggered();
log.trace("trigger: {} fired [{}] times", trigger.getFullName(),
trigger.getTimesTriggered());
trigger.setStartTime(intervalCalculation.calculateNextTryDate(nextAttemptNumber));
this.scheduler.rescheduleJob(trigger.getKey(), trigger);
}
} catch (SchedulerException e) {
log.error("job was not rescheduled <{}>", firedJobExecutionContext.getJobDetail(), e);
}
}