Unikaj usuwania timera na glassfish

Mam metodę z adnotacją @ Schedule, która jest wywoływana przez kontener raz na jakiś czas.

@Schedule(second = "*/5", minute = "*", hour = "*", persistent = false)
public void myTimerMethod() throws Exception {
    ...
}

Problem polega na pewnych warunkach chcę, aby ta metoda rzuciła wyjątek, aby spowodować wycofanie trwającej transakcji. Ale jeśli zrobię to więcej niż dwa razy, timer zostanie wymazany i nie będzie już wywoływany!

INFO: EJB5119:Expunging timer ['68@@1359143163781@@server@@domain1' 'TimedObject = MyBean' 'Application = My-War' 'BEING_DELIVERED' 'PERIODIC' 'Container ID = 89072805830524936' 'Fri Jan 25 21:49:30 CET 2013' '0' '*/5 # * # * # * # * # * # * # null # null # null # true # myTimerMethod # 0' ] after [2] failed deliveries

Wiem, że mogę skonfigurować przesunięcie timera w domenie.XML using

<domains>
    ...
    <configs>
        <config>
            ...
            <ejb-container session-store="${com.sun.aas.instanceRoot}/session-store">
               <ejb-timer-service>
                     <property name="reschedule-failed-timer" value="true"></property>
                </ejb-timer-service>
            </ejb-container>
            ...
        </config>
    </configs>
    ...
</domains>

Ale moje pytanie brzmi, Czy mogę skonfigurować to ustawienie podczas wdrażania moje podanie?

Nie można go znaleźć w:

glassfish-resources.xml
glassfish-ejb-jar.xml
glassfish-web.xml
Czy jest jakiś sposób, aby to zrobić programowo?

(moje uzasadnienie za umieszczaniem konfiguracji serwera w plikach konfiguracyjnych zamiast konfigurowania serwera jest więc moja aplikacja powinna być możliwa do zainstalowania bezpośrednio na świeżej instalacji glassfish)

Author: Carlo Pellegrini, 2013-01-26

2 answers

Użyłbym innego podejścia.

Zamiast rzucać wyjątek bezpośrednio z zaplanowanej metody, spróbuj wprowadzić poziom indrection jak w:

...
@Inject RealWorkHere realImplementation;

@Schedule(second = "*/5", minute = "*", hour = "*", persistent = false)
public void myTimerMethod(){
  try{
     realImplementation.myTimerMethodImpl()
  }catch (Exception x){
   // hopefully log it somewhere
  }
}
...

Gdzie RealWorkHere to fasola z rzeczywistą implementacją jak w:

@Stateless
public class RealWorkHere{
   @TransactionAttribute(REQUIRES_NEW)
   public void myTimerMethod() throws Exception {

   }
}

To przychodzi z korzyścią:

  • nie wrzucanie wyjątku do transakcji w kontenerze (unikanie w ten sposób usunięcia)
  • lepsze rejestrowanie wyjątku
  • jasne rozgraniczenie "prawdziwego" transakcja biznesowa

Zobacz też

 21
Author: Carlo Pellegrini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-02 05:31:01

Bieżący Glassfish do wersji 4 usuwa timer, jeśli podczas wykonywania metody wywołania zwrotnego timeout wystąpi wyjątek aplikacji .

Wyjątek aplikacji powoduje wycofanie bieżącej transakcji. W takiej sytuacji Glassfish ponownie powtarza bezbłędne wykonanie metody callback timeout. Jeśli nastąpi ponowne wycofanie, Glassfish usunie timer.

Zgłosiłem problem w GlassFish issue tracker, aby nie usuwać timera w przypadku o ekscesie. Glassfish wydaje się być jedynym serwerem aplikacji, który usuwa timer w przypadku wyjątku aplikacji. Zobacz glassfish #20749: Glassfish usuwa timer nawet jeśli metoda callback utrzymuje swój kontrakt aby uzyskać więcej szczegółów. Zapraszam do głosowania za moją sprawą.

Zgłosiłem również problem ze specyfikacją EJB, aby wyjaśnić, jak kontener EJB powinien zachowywać się w takich sytuacjach. Zobacz ejb-spec #111: Proszę wyjaśnić zachowanie kontenera, jeśli aplikacja wyjątek jest wyrzucany podczas wykonywania metody timer callback aby uzyskać więcej szczegółów.

 3
Author: Oliver,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-02 03:55:40