1

ジョブのトリガーを時々更新する必要があります。トリガーは 1 回しか起動されず、起動日は異なる場合があります。

したがって、この状況を管理する JobManager があります。アイデアは、特定の jobDetail が既に存在するかどうかを確認し、それを削除して新しいものを作成することでしたが、奇妙な動作とこの例外が発生しています。

したがって、私のコントローラーは次のようjobManager.createJob(interruttore, richiesta);に呼び出します。

public void createJob(Interruttore interruttore, Date richiesta) throws SchedulerException {

        JobDetail jobDetail = createJobDetail(interruttore);

        createOrUpdateScheduledJobs(interruttore, jobDetail, richiesta);
    }

これは createJob です

public JobDetail createJobDetail(Interruttore interruttore) throws SchedulerException {
        if (scheduler.getScheduler().checkExists(JobKey.jobKey("JobDetail" + interruttore.getNomeInterruttore()))) {
            logger.debug("jobDetail already present, delete it");scheduler.getScheduler().deleteJob(JobKey.jobKey("JobDetail" + interruttore.getNomeInterruttore()));
        } 
        logger.debug("Il jobDetail non esiste, lo creo");
        JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
        jobDetailFactoryBean.setJobClass(TimeoutJob.class);
        jobDetailFactoryBean.setName("JobDetail" + interruttore.getNomeInterruttore());
        jobDetailFactoryBean.setGroup("timeoutJobDetail");
        jobDetailFactoryBean.setDescription("Job for timeout");
        jobDetailFactoryBean.setDurability(true);

        Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("idInterruttore", interruttore.getIdInterruttore());
        jobDetailFactoryBean.setJobDataAsMap(map);
        jobDetailFactoryBean.afterPropertiesSet();
        logger.debug("JobDetail is " + jobDetailFactoryBean.toString());

        return jobDetailFactoryBean.getObject();

    }

そしてcreateOrUpdateScheduledJobs(interruttore, jobDetail, richiesta);、次のとおりです

public void createOrUpdateScheduledJobs(Interruttore interruttore, JobDetail jobDetail,
            Date richiesta) throws SchedulerException {


        // check if trigger exists
        boolean triggerExist = scheduler.getObject().checkExists(
                TriggerKey.triggerKey("myTrigger" + interruttore.getNomeInterruttore(), "timeoutTriggers"));
        logger.debug("Trigger exists? :" + triggerExist);

        if (triggerExist) { //replace trigger and reschedule job

            SimpleTrigger oldTrigger = (SimpleTrigger) scheduler.getScheduler().getTrigger(
                    TriggerKey.triggerKey("myTrigger" + interruttore.getNomeInterruttore(), "timeoutTriggers"));
            TriggerBuilder<SimpleTrigger> tb = oldTrigger.getTriggerBuilder();
            SimpleTrigger newTrigger = tb.startAt(richiesta).build();
            scheduler.getScheduler().rescheduleJob(((SimpleTrigger) oldTrigger).getKey(), newTrigger);
            logger.debug("new Trigger with firetime " + newTrigger.getNextFireTime());

        } else { // create a new one
            // creo il trigger e lo schedulo il job
            SimpleTriggerFactoryBean trigger = new SimpleTriggerFactoryBean();
            trigger.setName("myTrigger" + interruttore.getNomeInterruttore());
            trigger.setGroup("timeoutTriggers");
            trigger.setJobDetail(jobDetail.getObject());
            trigger.setStartTime(richiesta);
            trigger.setRepeatCount(0);
            trigger.afterPropertiesSet();
            try {
                scheduler.getScheduler().scheduleJob(jobDetail, trigger.getObject());
            } catch (SchedulerException e) {
                logger.error("Errore: ", e);
            }
            logger.debug("Trigger object is :" + trigger.getObject());
        }

    }

アプリケーションを起動すると、すべてが正常に動作し、2 回目にコントローラーがメソッドを呼び出すと、例外が発生します

org.quartz.ObjectAlreadyExistsException: Unable to store Job : 'timeoutJobDetail.JobDetailZona -2A', because one already exists with this identification.

新しい jobDetail を作成するメソッドは、削除する前の jobDetail インスタンスを見つけられませんが、新しいものを作成すると、それが実際に存在することがわかります...

4

1 に答える 1

0

TriggerKey と JobKey は Name と Group の両方で構成されます。

したがって、SimpleTriggerFactoryBean および JobDetailFactoryBean と同じように、TriggerKey および JobKey で Group を指定する必要があります。

申し訳ありませんが、正しく確認していませんが、JobKeyとTriggerKeyを変更すると. 2 回目の createJobDetail メソッドで Scheduler.deleteJob() メソッドが呼び出されます。

于 2016-12-31T07:27:37.320 に答える