问题
I am using EJB 3.0 Timers
in my application.
One thing about EJB Timers is that they are by default persistent which means that when ever there is server restart the Timers will automatically be invoked with out calling them again.
I have a requirement that these timers should be manually be started when ever server is restarted. For this I know we need to change some attribute in config XML which I don't know exact.
Where do I need to change the attribute to set persistent=false.
I am using Weblogic Server.
回答1:
In EJB 3.0 timers are persistent and there is no attribute to set to make them non-persistent. Possibility to affect this came with EJB 3.1 TimerConfig. Also WebLogic specific configuration does not provide any help.
回答2:
Create a programmatic Timer (@Timeout Method needed)
TimerConfig timerConfig = new TimerConfig("some info ...", false); timerService.createIntervalTimer(3000, 1000, timerConfig);
or create automatic timer: just annotate a method with @Schedule:
@Schedule(hour = "*", minute = "*", second = "*", persistent = false) private void myScheduledMethod(Timer timer) { // ... }
For this to work, you need to use EJB 3.1 or higher, that means you need a Java EE 6 (or higher) Server, or container supporting this ejb version. For Weblogic use need at least the version 12cR1.
- If this did not help, i would suggest to cancel all Timers at shutdown, i.e. in the
@PreDestroy
method of the corresponding bean.
I hope, i could help.
回答3:
This thread is old, but I think the concerns still apply nowadays. There is an attribute since EJB 3.1 to specify EJB persistency, as @mikko-maunu indicated, yet I've perceived it was modeled with two responsibilities:
- to have the schedule configuration persist after system reinitialization;
- to refire all eventually misfired triggers at system initialization.
I think the concepts above should have been modeled independently, so we could have a EJB timer stored on a database, and also have finer control over what to do with misfired triggers at system reinitialization, i.e. should them be retriggered or ignored.
Otherwise, it would seem awkward having a EJB Timer based job module where some of them are stored in a DB and others are not, just because we don't want to refire previous missed triggers for a job scheduled too frequently, running at an hourly basis, for example.
I've noticed, in JBoss 7.1 / Java EE 7, that keeping the schedule information in a database can potentially support a central control for a clustered configuration, instead of having repeated and independent instances of non-persistent time schedules. But the colateral effect is having, for a job triggered many times a day, all eventially misfired triggers fired at once at system reinitialization.
To have finer control over a persistent EJB Timer at restart time, we could, at the @PostConstruct method, check if the timer's getNextTimeout()
is a past time. If the timer should ignore misfired triggers, we could cancel the old timer and immediately create a new one, using the same scheduleExpression, so only future triggers will be considered. This seems very useful for timers scheduled to run many times a day.
Another possible, maybe simpler approach is, in the @Timeout method, check if the timer's next execution time, getNextTimeout()
, is before the current date and time, and then decide if previous, misfired triggers should be treated or discarded.
来源:https://stackoverflow.com/questions/8983334/how-to-make-ejb-timer-persistent-to-false