java - 为同一个 Quartz 作业创建第二个触发器时出现异常

标签 java quartz-scheduler

我想定义一个作业,然后使用一个简单的计划多次触发它。

作业是这样定义的:

scheduler.addJob(JobBuilder.newJob(ExampleJob.class)
    .storeDurably()
    .requestRecovery()
    .withDescription("Some nice description")
    .withIdentity(JOB_NAME, GROUP_NAME)
    .build(), false);

以这种方式安排它(第二次调用失败):

schedule(UUID.randomUUID(), Date.from(ZonedDateTime.now().plusSeconds(5).toInstant()));
schedule(UUID.randomUUID(), Date.from(ZonedDateTime.now().plusSeconds(10).toInstant()));

schedule 方法是这样实现的:

private void schedule(UUID userId, Date date) throws SchedulerException
{
    logger.info("Scheduling job {} in group {} at {}", JOB_NAME, GROUP_NAME, date);

    JobDetail job = scheduler.getJobDetail(JobKey.jobKey(JOB_NAME, GROUP_NAME));
    TriggerKey triggerKey = TriggerKey.triggerKey(TRIGGER_NAME + "_" + userId, GROUP_NAME.toString());
    Trigger trigger = newTrigger()
            .forJob(job)
            .withIdentity(triggerKey)
            .usingJobData(new JobDataMap(Collections.singletonMap(ExampleJob.USER_ID_KEY, userId.toString())))
            .startAt(date)
            .withSchedule(simpleSchedule().withMisfireHandlingInstructionFireNow())
            .build();
    scheduler.scheduleJob(trigger);
}

如前所述,第二次调用 schedule 失败。即使触发 key 是使用随机 UUID 构建的,也会出现重复输入错误:

java.lang.IllegalStateException: Failed to execute CommandLineRunner
        at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:803) ~[spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
        at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:784) ~[spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
        at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:771) ~[spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) ~[spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
        at nu.famroos.repro.quartz.duplicatekey.TheApplication.main(TheApplication.java:16) [main/:na]
Caused by: org.quartz.JobPersistenceException: Couldn't store trigger 'ExampleGroup.ExampleTrigger_73e40a3f-f5fd-4c1b-81a3-5ac09e014206' for 'ExampleGroup.ExampleJob' job:(conn:974) Duplicate entry 'schedulerFactoryBean' for key 'PRIMARY'
Query is: INSERT INTO QRTZ_SIMPLE_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP, REPEAT_COUNT, REPEAT_INTERVAL, TIMES_TRIGGERED)  VALUES('schedulerFactoryBean', ?, ?, ?, ?, ?), parameters ['ExampleTrigger_73e40a3f-f5fd-4c1b-81a3-5ac09e014206','ExampleGroup',0,0,0]
        at org.quartz.impl.jdbcjobstore.JobStoreSupport.storeTrigger(JobStoreSupport.java:1223) ~[quartz-2.2.1.jar:na]
        at org.quartz.impl.jdbcjobstore.JobStoreSupport$4.executeVoid(JobStoreSupport.java:1159) ~[quartz-2.2.1.jar:na]
        at org.quartz.impl.jdbcjobstore.JobStoreSupport$VoidTransactionCallback.execute(JobStoreSupport.java:3703) ~[quartz-2.2.1.jar:na]
        at org.quartz.impl.jdbcjobstore.JobStoreSupport$VoidTransactionCallback.execute(JobStoreSupport.java:3701) ~[quartz-2.2.1.jar:na]
        at org.quartz.impl.jdbcjobstore.JobStoreCMT.executeInLock(JobStoreCMT.java:245) ~[quartz-2.2.1.jar:na]
        at org.quartz.impl.jdbcjobstore.JobStoreSupport.storeTrigger(JobStoreSupport.java:1155) ~[quartz-2.2.1.jar:na]
        at org.quartz.core.QuartzScheduler.scheduleJob(QuartzScheduler.java:932) ~[quartz-2.2.1.jar:na]
        at org.quartz.impl.StdScheduler.scheduleJob(StdScheduler.java:258) ~[quartz-2.2.1.jar:na]
        at nu.famroos.repro.quartz.duplicatekey.QuartzRunner.schedule(QuartzRunner.java:69) ~[main/:na]
        at nu.famroos.repro.quartz.duplicatekey.QuartzRunner.run(QuartzRunner.java:53) ~[main/:na]
        at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:800) ~[spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
        ... 4 common frames omitted
Caused by: java.sql.SQLIntegrityConstraintViolationException: (conn:974) Duplicate entry 'schedulerFactoryBean' for key 'PRIMARY'
Query is: INSERT INTO QRTZ_SIMPLE_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP, REPEAT_COUNT, REPEAT_INTERVAL, TIMES_TRIGGERED)  VALUES('schedulerFactoryBean', ?, ?, ?, ?, ?), parameters ['ExampleTrigger_73e40a3f-f5fd-4c1b-81a3-5ac09e014206','ExampleGroup',0,0,0]
        at org.mariadb.jdbc.internal.util.ExceptionMapper.get(ExceptionMapper.java:128) ~[mariadb-java-client-1.5.5.jar:na]
        at org.mariadb.jdbc.internal.util.ExceptionMapper.getException(ExceptionMapper.java:101) ~[mariadb-java-client-1.5.5.jar:na]
        at org.mariadb.jdbc.internal.util.ExceptionMapper.throwAndLogException(ExceptionMapper.java:77) ~[mariadb-java-client-1.5.5.jar:na]
        at org.mariadb.jdbc.MariaDbStatement.executeQueryEpilog(MariaDbStatement.java:224) ~[mariadb-java-client-1.5.5.jar:na]
        at org.mariadb.jdbc.MariaDbServerPreparedStatement.executeInternal(MariaDbServerPreparedStatement.java:411) ~[mariadb-java-client-1.5.5.jar:na]
        at org.mariadb.jdbc.MariaDbServerPreparedStatement.execute(MariaDbServerPreparedStatement.java:359) ~[mariadb-java-client-1.5.5.jar:na]
        at org.mariadb.jdbc.MariaDbServerPreparedStatement.executeUpdate(MariaDbServerPreparedStatement.java:348) ~[mariadb-java-client-1.5.5.jar:na]
        at org.quartz.impl.jdbcjobstore.SimpleTriggerPersistenceDelegate.insertExtendedTriggerProperties(SimpleTriggerPersistenceDelegate.java:63) ~[quartz-2.2.1.jar:na]
        at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.insertTrigger(StdJDBCDelegate.java:1098) ~[quartz-2.2.1.jar:na]
        at org.quartz.impl.jdbcjobstore.JobStoreSupport.storeTrigger(JobStoreSupport.java:1220) ~[quartz-2.2.1.jar:na]
        ... 14 common frames omitted
Caused by: org.mariadb.jdbc.internal.util.dao.QueryException: Duplicate entry 'schedulerFactoryBean' for key 'PRIMARY'
Query is: INSERT INTO QRTZ_SIMPLE_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP, REPEAT_COUNT, REPEAT_INTERVAL, TIMES_TRIGGERED)  VALUES('schedulerFactoryBean', ?, ?, ?, ?, ?), parameters ['ExampleTrigger_73e40a3f-f5fd-4c1b-81a3-5ac09e014206','ExampleGroup',0,0,0]
        at org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol.getResult(AbstractQueryProtocol.java:1114) ~[mariadb-java-client-1.5.5.jar:na]
        at org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol.executePreparedQuery(AbstractQueryProtocol.java:602) ~[mariadb-java-client-1.5.5.jar:na]
        at org.mariadb.jdbc.MariaDbServerPreparedStatement.executeInternal(MariaDbServerPreparedStatement.java:398) ~[mariadb-java-client-1.5.5.jar:na]
        ... 19 common frames omitted

更糟糕的是:在此之后,Quartz 数据不一致到调度程序无法启动的程度:

java.lang.IllegalStateException: Failed to execute CommandLineRunner
        at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:803) ~[spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
        at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:784) ~[spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
        at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:771) ~[spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) ~[spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
        at nu.famroos.repro.quartz.duplicatekey.TheApplication.main(TheApplication.java:16) [main/:na]
Caused by: org.quartz.SchedulerConfigException: Failure occured during job recovery.
        at org.quartz.impl.jdbcjobstore.JobStoreSupport.schedulerStarted(JobStoreSupport.java:692) ~[quartz-2.2.1.jar:na]
        at org.quartz.core.QuartzScheduler.start(QuartzScheduler.java:567) ~[quartz-2.2.1.jar:na]
        at org.quartz.impl.StdScheduler.start(StdScheduler.java:142) ~[quartz-2.2.1.jar:na]
        at nu.famroos.repro.quartz.duplicatekey.QuartzRunner.run(QuartzRunner.java:50) ~[main/:na]
        at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:800) ~[spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
        ... 4 common frames omitted
Caused by: org.quartz.JobPersistenceException: Couldn't retrieve trigger: No record found for selection of Trigger with key: 'ExampleGroup.ExampleTrigger_73e40a3f-f5fd-4c1b-81a3-5ac09e014206' and statement: SELECT * FROM QRTZ_SIMPLE_TRIGGERS WHERE SCHED_NAME = 'schedulerFactoryBean' AND TRIGGER_NAME = ? AND TRIGGER_GROUP = ?
        at org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveTrigger(JobStoreSupport.java:1533) ~[quartz-2.2.1.jar:na]
        at org.quartz.impl.jdbcjobstore.JobStoreSupport.recoverMisfiredJobs(JobStoreSupport.java:979) ~[quartz-2.2.1.jar:na]
        at org.quartz.impl.jdbcjobstore.JobStoreSupport.recoverJobs(JobStoreSupport.java:866) ~[quartz-2.2.1.jar:na]
        at org.quartz.impl.jdbcjobstore.JobStoreSupport$1.executeVoid(JobStoreSupport.java:838) ~[quartz-2.2.1.jar:na]
        at org.quartz.impl.jdbcjobstore.JobStoreSupport$VoidTransactionCallback.execute(JobStoreSupport.java:3703) ~[quartz-2.2.1.jar:na]
        at org.quartz.impl.jdbcjobstore.JobStoreSupport$VoidTransactionCallback.execute(JobStoreSupport.java:3701) ~[quartz-2.2.1.jar:na]
        at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock(JobStoreSupport.java:3787) ~[quartz-2.2.1.jar:na]
        at org.quartz.impl.jdbcjobstore.JobStoreSupport.recoverJobs(JobStoreSupport.java:834) ~[quartz-2.2.1.jar:na]
        at org.quartz.impl.jdbcjobstore.JobStoreSupport.schedulerStarted(JobStoreSupport.java:690) ~[quartz-2.2.1.jar:na]
        ... 8 common frames omitted
Caused by: java.lang.IllegalStateException: No record found for selection of Trigger with key: 'ExampleGroup.ExampleTrigger_73e40a3f-f5fd-4c1b-81a3-5ac09e014206' and statement: SELECT * FROM QRTZ_SIMPLE_TRIGGERS WHERE SCHED_NAME = 'schedulerFactoryBean' AND TRIGGER_NAME = ? AND TRIGGER_GROUP = ?
        at org.quartz.impl.jdbcjobstore.SimpleTriggerPersistenceDelegate.loadExtendedTriggerProperties(SimpleTriggerPersistenceDelegate.java:95) ~[quartz-2.2.1.jar:na]
        at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.selectTrigger(StdJDBCDelegate.java:1819) ~[quartz-2.2.1.jar:na]
        at org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveTrigger(JobStoreSupport.java:1531) ~[quartz-2.2.1.jar:na]
        ... 16 common frames omitted

非常欢迎就如何解决这个问题提出建议。 完整的复制品可用 here on GitHub .

最佳答案

原来是 Liquibase 模式定义中的问题。

主键是这样定义的:

    - addPrimaryKey:
        columnNames: SCHED_NAME
        tableName: QRTZ_SIMPLE_TRIGGERS
        constraintName: PK_QRTZ_SIMPLE_TRIGGERS

应该是这样的:

    - addPrimaryKey:
        columnNames: SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP
        tableName: QRTZ_SIMPLE_TRIGGERS
        constraintName: PK_QRTZ_SIMPLE_TRIGGERS

关于java - 为同一个 Quartz 作业创建第二个触发器时出现异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42911846/

相关文章:

java - 来自列表元素的 Android Fragment 事务

java - 更新 "ERROR: column "的 sql 使用了“关系 "account"不存在”,即使它确实存在

quartz-scheduler - 使用 Quartz.net 配置 ADOJobStore

spring - quartz jboss spring 多个 webapp

java - Quartz 作业抛出 InvalidDataAccessApiUsageException : no transaction is in progress;

grails - 如何在另一个作业完成时触发作业?

java - JapserReport 中的覆盖页码未反射(reflect)在最终 PDF 中

java - 可序列化和接口(interface) : Parcelable encountered IOException writing serializable object

java - 类型转换和泛型,有什么性能差异?

java - 我可以使用 Quartz 配置一种触发隔离吗?