3 таймера EJB выполняются несколько раз - PullRequest
4 голосов
/ 29 марта 2012

У меня есть некоторые проблемы с таймером EJB 3, когда он запускается более одного раза. Вместо того, чтобы настраивать таймер в аннотации, я использую программную настройку, как объясняется во многих блогах. Вот мой код:

@Singleton
@Startup
public class AutoAssignTask extends AbstractDirectoryMonitor {

    @Resource
    private TimerService timer;

    @Inject
    @PropertyResource(name = "timer.hour", resource = "/DL4/app.conf")
    private String hour;
    @Inject
    @PropertyResource(name = "timer.minute", resource = "/DL4/app.conf")
    private String minute;
    @Inject
    @PropertyResource(name = "timer.second", resource = "/DL4/app.conf")
    private String second;

    @EJB
    private AutoAssignService autoAssignService;

    @PostConstruct
    public void init() {
            // initializing with an expression.
        this.initSchedule();
    }
    protected void initSchedule() {
        ScheduleExpression exp = new ScheduleExpression();
        if (!StringUtils.isEmpty(this.getHour())) {
            exp.hour(this.getHour());
        }
        if (!StringUtils.isEmpty(this.getMinute())) {
            exp.minute(this.getMinute());
        }
        if (!StringUtils.isEmpty(this.getSecond())) {
            exp.second(this.getSecond());
        }
        this.getTimer().createCalendarTimer(exp);
    }

    @Timeout
    public void process() {
        // do something
        AutoAssignTask.LOG.info("starting job.");
    }

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

Есть идеи, что не так?

Ответы [ 2 ]

3 голосов
/ 16 февраля 2017

Вопрос может быть довольно старым, но выглядит (для JBoss EAP 7 как минимум), что таймеры хранятся в %JBOSS_HOME%\standalone\data\timer-service-data в формате XML. Так что вполне вероятно, что он читает из их кратного ScheduleExpression.

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

1 голос
/ 30 марта 2012

Несколько мыслей:

  1. Обновите код, чтобы отобразить метод initSchedule(). Проблема может быть в ScheduleExpression.
  2. Вы никогда не можете исключить ошибки сервера. Убедитесь, что ваш @PostConstruct не вызывается дважды, что произошло бы, если бы ваш сервер создал два синглтона (проблема общего состояния гонки).
  3. Поскольку у вас есть некоторое подклассификация, убедитесь, что вы знаете, что, если AutoAssignTask будет дополнительно подклассифицирован, то @PostConstruct из AutoAssignTask будет по-прежнему вызываться. Проще говоря, метод @PostConstruct для суперклассов EJB также вызывается - сначала самый старый родитель.

Для чисел 2 и 3 будет работать простой статический оператор AtomicInteger и log:

public class AutoAssignTask extends AbstractDirectoryMonitor {

    private static final AtomicInteger instances = new AtomicInteger();

    @PostConstruct
    public void init() {
        System.out.println("AutoAssignTask instance "+instances.incrementAndGet());
        //....
    }
}

...