Аннотация Spring 3.0 @Scheduled не работает должным образом

Я использую аннотацию @Scheduled, чтобы функция myProcess() в приложении Spring MVC (версия 3.0.6.RELEASE, работающая на Apache Tomcat/7.0.26) запускалась один раз в час (3 600 000 мс = 1 час):

@Scheduled(fixedRate = 3600000)
public void myProcess() { ... }

Функция выполняется, как и ожидалось, но не утром (см. пример времени в журнале ниже за последние 2 дня). Это происходит каждый день. Я не вижу исключений в файлах журнала. Есть ли у вас какие-либо идеи относительно того, что может быть причиной этого странного поведения?


Feb 13 02:11:15
Feb 13 03:11:16 
Feb 13 06:17:34
Feb 13 06:45:55 
Feb 13 07:03:22
Feb 13 07:31:57
Feb 13 08:11:16 
Feb 13 09:11:18
Feb 13 10:11:18 
Feb 13 11:11:28 

Feb 14 01:11:37
Feb 14 02:11:29
Feb 14 03:11:29 
Feb 14 06:19:51
Feb 14 06:49:17
Feb 14 07:35:57
Feb 14 08:11:29
Feb 14 09:11:35

person Gruber    schedule 15.02.2013    source источник
comment
Какую версию Spring вы используете?   -  person sp00m    schedule 15.02.2013
comment
@sp00m: Спасибо, версия Spring 3.0.6.RELEASE. Я обновил вопрос с этой информацией.   -  person Gruber    schedule 15.02.2013


Ответы (2)


У меня была такая же проблема, но с использованием атрибута cron:

// every day at midnight
@Scheduled(cron = "0 0 0 * * ?")
public void myProcess() {
}

Я не могу вспомнить его поведение, но это было не то, что я ожидал. Наконец я обнаружил, что это, вероятно, зависит от ошибки в Spring 3.0.x. Решение, которое я попробовал (и которое сработало), состояло в том, чтобы объявить задачу в файле applicationContext.xml, в дополнение к аннотации:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">

    ...

    <!-- scheduling and async -->
    <task:annotation-driven />
    <task:scheduled-tasks>
      <task:scheduled ref="myProcessHandler" method="myProcess" fixed-delay="0" />
    </task:scheduled-tasks>
    <bean id="myProcessHandler" class="path.to.MyProcessHandler" />

    ...

</beans>

Даже если атрибут fixed-delay необходим для исправления ошибки (насколько мне известно), он не принимается во внимание, а атрибут cron аннотации @Scheduled учитывается.

Я надеюсь, это поможет.

person sp00m    schedule 15.02.2013
comment
О, возможная ошибка. Я подозревал это. Я рассмотрю предложенное вами решение и посмотрю, смогу ли я заставить его работать. - person Gruber; 15.02.2013
comment
Не уверен, что я что-то упустил, но если я использовал и XML, и аннотацию, я получил два одновременных процесса. Только XML тоже не работал, потому что событие срабатывало только один раз и никогда больше. Поэтому я переключился на cron и добавил <task:scheduled ref="myProcessHandler" method="myProcess" cron="0 0 * * * ?" /> в root-context.xml (пришлось удалить <task:annotation-driven />). Это, наконец, сработало. - person Gruber; 21.02.2013

Я не могу дать вам ответ на конкретный вопрос, я бы попробовал использовать последнюю версию Spring (3.2), потому что между 3.0 и 3.1, насколько мне известно, в этой области были реализованы значительные изменения.

Однако, по моему опыту, я обнаружил, что cronTrigger намного лучше во всех случаях (конечно, он может делать все, что может fixedRate, и многое другое).

Просто определите свои свойства следующим образом:

<util:properties id="props" location=classpath:/application.properties" />
<context:property-placeholder properties-ref="props"  />
<task:annotation-driven />

А затем используйте его:

@Scheduled(cron = "${cron.expression}")
public void scheduledTask() throws .. { .. }

Где в application.properties у вас что-то вроде: cron.expression = 0 0/60 * * * ?

person abalogh    schedule 15.02.2013
comment
Да, cron кажется мне лучшим выбором. Мне нравится fixedRate, потому что он запускается сразу же, как только я запускаю приложение, что очень удобно, когда дело доходит до отладки. В противном случае мне нужно дождаться cron времени. - person Gruber; 15.02.2013
comment
Да, это правда. Однако вы можете иметь оба :) - person abalogh; 15.02.2013
comment
Я пробовал @Scheduled(cron="0 0 * * * ?"). Тем не менее появляется тот же неправильный образец выполнения. Это придает больший вес комментарию sp00m о возможных ошибках в Spring 3.0.x. - person Gruber; 20.02.2013
comment
Как я уже предлагал, сделайте обновление до 3.2, насколько мне известно, там нет ничего, что зависит от Spring 3.0.x, так почему бы и нет. - person abalogh; 20.02.2013
comment
Я работаю с устаревшей системой и беспокоюсь о проблемах обратной несовместимости между 3.2 и 3.0. Стоимость обновления и проверки того, что все работает должным образом, в настоящее время слишком высока. Рано или поздно, конечно, мне нужно будет обновиться. - person Gruber; 21.02.2013