2016-08-04 90 views
12

Stworzyłem funkcję doWork() który jest zaplanowane codziennie o 1:00, funkcja jest następująca:Java timera Usługa działa wielokrotnie

@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); 
    } 

Problemem jest to, że funkcja ta działa więcej niż jeden raz , nie zgodnie z planem.

Po utworzeniu go działał dokładnie tak, jak powinien (codziennie dokładnie o 1:00:00). Kilka dni później zaczęło działać o godzinie 1:03:00 (co nie ma sensu, ponieważ nie ma w nim miejsca i nie ma przestojów na serwerze). Po tym funkcja zaczęła działać więcej niż jeden raz z bardzo krótkimi przerwami pomiędzy (różnicą sekund)

Czy ktoś wie, co może spowodować to, lub powiedz mi, co mogę zrobić, aby to naprawić?

[EDIT]: szczegóły Środowisko

Application Server: WebSphere Application Server 8.5.5

IDE: Rational Application Developer 9.1

Database Management System: IBM DB2 10.1

+3

Który serwer aplikacji (i wersja) używasz? Może to pomóc w sprawdzeniu, czy są problemy związane z tym AS. –

+0

W jaki sposób rejestrujesz czas uruchomienia usługi? Wynik dziennika? Czas systemowy/serwerowy? – kolossus

+0

@ OlivierGrégoire Używam serwera WebSphere Application Server 8.5.5 –

Odpowiedz

1

I sądzisz, że obserwujesz kontener próbujący ponowić próbę wykonania nieudanego połączenia doWork().

Usługa zegara EJB jest transakcyjna.

Jeśli w wyniku wykonania metody limitu czasu zostanie zgłoszony wyjątek środowiska wykonawczego, transakcja zostanie wycofana, a kontener spróbuje ponownie wykonać metodę limitu czasu. Zobacz § 18.2.8 Transakcje specyfikacji EJB 3.1.

Dodatkowo, jeśli upłynie limit czasu transakcji, niektóre implementacje po prostu oznaczy bieżącą transakcję do wycofania i będą kontynuować przetwarzanie. Spowoduje to, że połączenie z zegarem w końcu się nie powiedzie i nastąpi próba ponowienia.

Ten mechanizm ponawiania nie jest dobrze określony, a rzeczywiste zachowanie różni się w zależności od implementacji. Niektóre będą się powtarzać na zawsze, a inne zrezygnują po kilku próbach. Na przykład WebSphere udostępnia sposób określania strategii ponawiania. Zobacz Creating timers using the EJB timer service for enterprise beans.

Na koniec, jeśli aplikacja działa w wielu węzłach, prawdopodobnie istnieje czasomierz działający na instancję serwera. Według §18.2.3 Nietrwałe liczniki spec:

do automatycznych Nietrwałe timerów pojemnik tworzy nowy nietrwałe czasowym w trakcie inicjalizacji stosowania dla każdego JVM w poprzek którego jest on rozłożony.

Jeśli wszystkie te czynności wykonują to samo zadanie, to prawdopodobnie spowoduje to chaos generujący błędy, wycofywanie i kolejne próby.

+0

Zgodnie z dziennikami metoda doWork() działa pomyślnie za pierwszym razem, a następnie uruchamia się ponownie i kończy się niepowodzeniem i kontynuuje próbę. Chodzi o to, że pobiera plik csv, analizuje go, usuwa wszystko z bazy danych, a następnie przetwarza przeanalizowane dane. Zgodnie z logami, przy pierwszej próbie baza danych jest opróżniana i ponownie wypełniana pomyślnie, a następnie metoda jest uruchamiana ponownie i kontynuuje ponawianie próby, a ja kończę z pustą bazą danych. Ponieważ pierwsza próba zakończyła się pomyślnie, nie widzę powodu, dla którego metoda zostanie ponownie wywołana po pierwszej próbie? –

+0

Nadal musisz podać więcej szczegółów na temat swojego środowiska, zanim ktokolwiek będzie mógł spekulować dalej. Dodatkowo w jaki sposób możesz mieć pewność, że początkowa transakcja zakończyła się pomyślnie - tj. Po zakończeniu 'doWork()' wyjścia? –

+0

Jestem pewna, że ​​udało się ukończyć pomyślnie przy pierwszej próbie z powodu logowania. Sprawdzając dzienniki bazy danych, mogłem zauważyć, że rekordy z przeanalizowanego pliku .csv zostały pomyślnie zapisane w bazie danych. Następnie kontynuuje ponawianie próby, usuwa wszystko z bazy danych i kończy się pustą bazą danych. Proszę sprawdzić szczegóły edycji dla środowiska –