Служба таймера Java работает несколько раз

Я создал функцию doWork(), которая должна запускаться каждый день в 1:00 утра, функция следующая:

@Schedule(hour = "1", persistent = false)
    public void doWork()
    {
        System.out.println("Starting .....\nTIME: " + System.currentTimeMillis());
        System.out.println("this : " + this);

        //Some code here, if-conditions and try/catch blocks. No loops

        System.out.println("Exiting .....\nTIME: " + System.currentTimeMillis());
        System.out.println("this : " + this);
    }

Проблема заключается в том, что эта функция запускается более одного раза, а не по расписанию.

Как только я его создал, он работал точно так, как ожидалось (каждый день в 1:00:00 точно). Несколько дней спустя он начал работать в 1:03:00 (что не имеет никакого смысла, поскольку оно нестабильно, и в любом случае на сервере не было простоя). После этого функция запускалась более одного раза с очень короткими интервалами между (разница секунд)

Кто-нибудь знает, что может вызвать это, или скажите мне, что я могу сделать, чтобы исправить это?

[EDIT]: Сведения о средах

Сервер приложений: WebSphere Application Server 8.5.5

IDE: Rational Application Developer 9.1

Система управления базами данных: IBM DB2 10.1

Ответ 1

Я считаю, что вы наблюдаете за контейнером, пытающимся повторить неудачный вызов doWork().

Служба таймера EJB является транзакционной.

Если выполнение метода тайм-аута выбрасывает исключение во время выполнения, транзакция будет отброшена назад, и контейнер попытается снова выполнить метод тайм-аута. См. §18.2.8. Транзакции спецификации EJB 3.1.

Кроме того, если истекает время ожидания транзакции, некоторые реализации просто отметят текущую транзакцию для отката и продолжат обработку. Это приведет к сбою вызова таймера, и попытка повторения будет предпринята.

Этот механизм повторения недостаточно определен, и фактическое поведение варьируется от реализации к реализации. Некоторые вернутся навсегда, а другие будут сдаваться после нескольких попыток. Например, WebSphere предоставляет способ указания стратегии повтора. См. Создание таймеров с использованием службы таймера EJB для предприятия beans.

Наконец, если ваше приложение работает на нескольких узлах, вы, вероятно, используете таймер для экземпляра сервера. Согласно §18.2.3 Непостоянные таймеры спецификации:

Для автоматических нестационарных таймеров контейнер создает новый непостоянный таймер во время инициализации приложения для каждой JVM, через которую распространяется контейнер.

Если все они выполняют одну и ту же задачу, это может вызвать достаточный хаос для генерации ошибок, откатов и последующих попыток.