Unable to store Job:'todoJobGroup.1183894449946624', because one already exists with this identification.

在今天迭代上线后,测试突然发现了一个bug.去pro环境看了一下log

2019-08-02 17:52:40.756 ERROR 18408 --- [nio-8084-exec-2] c.g.common.eventbus.EventBus.default     : Exception thrown by subscriber method onEvent(com.decobim.todo.job.InAddTriggerEvent) on subscriber com.decobim.ops.quartz.QuartzEvent@6e9ea96d when dispatching event: InAddTriggerEvent(todoItemId=1183894449946624, reminderTime=1564743006000)

org.quartz.ObjectAlreadyExistsException: Unable to store Job : 'todoJobGroup.1183894449946624', 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.decobim.ops.quartz.QuartzEvent.onEvent(QuartzEvent.java:56) ~[classes/:na]

错误描述是 org.quartz.ObjectAlreadyExistsException: Unable to store Job : 'todoJobGroup.1183894449946624', because one already exists with this identification.
不能存储job,因为相同的job已经存在了.

那就很容易解决,问题出现在这行:

//at com.decobim.ops.quartz.QuartzEvent.onEvent(QuartzEvent.java:56) ~[classes/:na]
//相应代码为: 
scheduler.scheduleJob(job, trigger);

因为相同的job名已经存在,所以要做的就是删除之前的该名称的job. 问题出现在,本应该被删除的job,实际是被暂停了.又去翻了一下Scheduler的代码,看了一下注释(注释写的真的挺全的)

/**
 * Pause the <code>{@link Trigger}</code> with the given key.
 * 
 * @see #resumeTrigger(TriggerKey)
 */
void pauseTrigger(TriggerKey triggerKey)
    throws SchedulerException;

/**
 * Remove the indicated <code>{@link Trigger}</code> from the scheduler.
 * 
 * <p>If the related job does not have any other triggers, and the job is
 * not durable, then the job will also be deleted.</p>
 */
boolean unscheduleJob(TriggerKey triggerKey)
    throws SchedulerException;

之前用的是pauseTrigger 作用只是暂停这个trigger,实际应该用unscheduleJob

//scheduler.pauseTrigger(new TriggerKey(todoItemId, TODO_TRIGGER_GROUP));
// 修改为

// 从pause改为unSchedule pause只是暂停,unSchedule是从数据库中删除
scheduler.unscheduleJob(new TriggerKey(todoItemId, TODO_TRIGGER_GROUP));

在scheduleJob这边也做个防范:

/**
 * Remove (delete) the <code>{@link org.quartz.Trigger}</code> with the
 * given key, and store the new given one - which must be associated
 * with the same job (the new trigger must have the job name & group specified) 
 * - however, the new trigger need not have the same name as the old trigger.
 * 
 * @param triggerKey identity of the trigger to replace
 * @param newTrigger
 *          The new <code>Trigger</code> to be stored.
 * 
 * @return <code>null</code> if a <code>Trigger</code> with the given
 *         name & group was not found and removed from the store (and the 
 *         new trigger is therefore not stored), otherwise
 *         the first fire time of the newly scheduled trigger is returned.
 */
Date rescheduleJob(TriggerKey triggerKey, Trigger newTrigger) 
    throws SchedulerException;

//scheduler.scheduleJob(job, trigger);
// 修改为:

try {
    scheduler.scheduleJob(job, trigger);
}catch (ObjectAlreadyExistsException e){
    // 放置出现triggerKey相同的情况,无论如何 后添加的trigger要覆盖老trigger
    TriggerKey triggerKey = new TriggerKey(todoItemId, TODO_TRIGGER_GROUP);
    scheduler.rescheduleJob(triggerKey,trigger);
}

   转载规则


《Unable to store Job:'todoJobGroup.1183894449946624', because one already exists with this identification.》 echi1995 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
初见cglib 初见cglib
今天在看spring文档的时候看到了cglib代理. 出于好奇,就去搜索了一下.深入理解CGLIB动态代理机制并没有很深入的去了解这个代理机制,只是简单的看了一下怎么用. 毕竟现在主要还是学习spring文档. 之前也看过java中的动
下一篇 
SpringBoot启动时,不想连接mysql SpringBoot启动时,不想连接mysql
在拆分服务的时候,因为当前服务没有使用到mysql数据库。便把mysql配置文件删除。结果报错: *************************** APPLICATION FAILED TO START **************
  目录