Весенняя партия и весенний задатчик


Таким образом, у меня есть два задания с отдельными тасклетами каждое.

Джоба сделает:

sysout("JobA executed at "+new Date());

Джобб сделает:

sysout("JobB executed at "+new Date());

Оба из которых могут быть либо в отдельном xml, либо в одном xml. Но в настоящее время у меня есть отдельный xml для обоих. Я определил обе работы одинаково следующим образом:

<batch:job id="task_scheduler" restartable="false">
    <batch:step id="test_task_scheduler"
        allow-start-if-complete="true">
        <batch:tasklet ref="job1" />
    </batch:step>
</batch:job>

<bean id="job1" class="com.irsis.batch.tasklet.TestOut" />
<bean id="runScheduler" class="com.irsis.batch.taskscheduler.RunScheduler1" />

Затем в моем application-context.xml я определил планировщик задач

    <task:scheduled-tasks>
    <task:scheduled ref="runScheduler1" method="run"
        cron="*0 0/1 * 1/1 * ? " />
    <task:scheduled ref="runScheduler2" method="run"
        cron="0 0/2 * 1/1 * ? "/>
</task:scheduled-tasks>

При запуске у меня есть это исключение

Could not autowire field: org.springframework.batch.core.Job com.irsis.batch.taskscheduler.RunScheduler1.job; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.batch.core.Job] is defined: expected single matching bean but found 2: task_scheduler,task_scheduler2

Кстати, это мой RunScheduler1.Ява файл

@Autowired 
JobLauncher jobLauncher;

@Autowired 
Job job;

public void run() {


    try {

        String dateParam = new Date().toString();
        JobParameters param = new JobParametersBuilder().addString("date",
                dateParam).toJobParameters();

        JobExecution execution = jobLauncher.run(job, param);
        System.out.println("Exit Status : " + execution.getStatus());

    } catch (Exception e) {
        e.printStackTrace();
    }

    System.out.println("Done");

}

Теперь мой вопрос: возможно ли для spring batch иметь несколько заданий? Потому что из того, что я вижу из моего исключения, это то, что он ожидает только одну работу.

Хотя я попробовал другой способ. То, что я сделал, было чем-то вроде этого в контексте приложения.xml

<batch:job id="job" restartable="false">
    <batch:step id="test_task_scheduler"
        allow-start-if-complete="true">
        <batch:tasklet ref="job1" />
    </batch:step>
</batch:job>

<bean id="job1" class="com.irsis.batch.tasklet.TestOut" />
<bean id="runScheduler1" class="com.irsis.batch.taskscheduler.RunScheduler1" />


    <batch:job id="job2" restartable="false">
    <batch:step id="test_task2_scheduler"
        allow-start-if-complete="true">
        <batch:tasklet ref="job2" />
    </batch:step>
</batch:job>

<bean id="job2" class="com.irsis.batch.tasklet.TestOut2" />
<bean id="runScheduler2" class="com.irsis.batch.taskscheduler.RunScheduler2" />


<task:scheduled-tasks>
    <task:scheduled ref="runScheduler1" method="run"
        cron="*0 0/1 * 1/1 * ? " />

</task:scheduled-tasks>

<task:scheduled-tasks>
    <task:scheduled ref="runScheduler2" method="run"
        cron="0 0/2 * 1/1 * ? " />
</task:scheduled-tasks>

Он запустил первое задание, а затем всякий раз, когда он пытается запустить второе задание, появляется это исключение:

PreparedStatementCallback; SQL [вставить в BATCH_JOB_INSTANCE(JOB_INSTANCE_ID, JOB_NAME, JOB_KEY, VERSION)
ценности (?, ?, ?, ?)]; Ошибка: повторяющееся значение ключа нарушает уникальность ограничение" job_inst_un " подробно: ключ (job_name, job_key)=(задание, 8a87688793625c6f3b8f982dbe6689d2) уже существует.; вложенным исключением является орг..в PostgreSQL.утиль.PSQLException: ошибка: повторяющееся значение ключа нарушает уникальное ограничение" job_inst_un " деталь: ключ (job_name, job_key)=(job, 8a87688793625c6f3b8f982dbe6689d2) уже существует.

Обновление: я думаю, что собираюсь изменить свой подход. Еще один вопрос ссылка Здесь

Спасибо,
Jet

3 2

3 ответа:

Это не исключение из партии пружин, это скорее исключение из обычной проводки пружин. Причина в том, что у вас, вероятно, есть @Autowired аннотация для свойства Job в вашем RunScheduler1. Теперь в вашем контексте у вас есть два задания: одно с идентификатором task_scheduler и одно с идентификатором task_scheduler2, и Spring не знает, в каком конкретном из них вы хотите подключиться.

Простое исправление будет состоять в том, чтобы просто удалить @Autowired и ввести ссылку через xml следующим образом:

<bean id="runScheduler" class="com.irsis.batch.taskscheduler.RunScheduler1" >
    <property name="job" ref="task_scheduler"/>
</bean>

обновление: Ваш уникальный исключение, связанное с ограничением, на самом деле возможно - два задания считаются одинаковыми, если параметры для обоих заданий совпадают точно, в вашем случае каким-то образом даты сталкиваются(здесь я чувствую небольшую ошибку с Spring batch из-за точности метода toString даты) для двух разных экземпляров задания и, следовательно, проблема. Могу ли я предложить добавить еще один параметр (скажем, ваш пользовательский UUID с помощью UUID.randomUUID().toString()), это гарантирует, что два параметра задания абсолютно уникальны и должны можно рассматривать как два совершенно разных экземпляра задания.

Я думаю, что вы передаете один и тот же параметр задания снова и снова... за выполнение задания. Попробуйте изменить параметр задания для каждого запуска.

Как--

JobParameters jobParameters = new JobParametersBuilder()
          .addLong("time",System.currentTimeMillis())
          .toJobParameters();

JobExecution execution = jobLauncher.run(job, jobParameters);

Это проблема впрыска пружины.У них может быть какой-то конфликт в названии ссылки.Возможно, Вам потребуется использовать @Qualifier, чтобы обойти эту проблему.Пожалуйста, проверьте эту ссылку. http://www.mkyong.com/spring/spring-autowiring-qualifier-example/