I have a scheduling singleton where I am trying to manage multiple calendar timers. I have a service that I'm calling every 30 minutes. However, once per day (e.g. 3 AM) I need to call this same service to do something different.
Main question - can you have multiple timers in the same Singleton?
When I look at the code, it seems to me that at some point (3 AM) the two timers will collide and I will get a ConcurrentAccessTimeoutException and one of them won't run. For example:
Caused by: javax.ejb.ConcurrentAccessTimeoutException: WFLYEJB0241: EJB 3.1 PFD2 4.8.5.5.1 concurrent access timeout on TestBean- could not obtain lock within 5000MILLISECONDS
Maybe if I create the 3AM timer first in PostConstruct there will be more likelihood that it will run and lock out the every30 timer? But even if that's possible it seems a) little hokey b) leaving things to chance. I can live with the every30 timer not getting run at 3 AM but the single run one can't miss since it's the only time it gets run. Another option would be to set the every30 timer to something where it wouldn't run at the same time as the once a day timer but again, hokey.
Here is my code:
@Singleton
@Startup
@TransactionManagement(TransactionManagementType.CONTAINER)
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class SomeScheduler
{
@Resource
private TimerService timerService;
@Inject
@ConfiguredProperty(key="scheduleExpression1", mandatory=false, defaultValue="minute=*/30; hour=*")
private ScheduleExpression scheduleExpression1;
@Inject
@ConfiguredProperty(key="scheduleExpression2", mandatory=false, defaultValue="hour=3; dayOfWeek=*")
private ScheduleExpression scheduleExpression2;
private Timer timer1;
private Timer timer2;
@PostConstruct
private void postConstruct()
{
timer1 = timerService.createCalendarTimer(scheduleExpression1, new TimerConfig("every30", false));
timer2 = timerService.createCalendarTimer(scheduleExpression2, new TimerConfig("at3AM", false));
}
@Timeout
public void handler (Timer timer)
{
if (Objects.equals(timer.getInfo(), "every30"))
{
// Call Something
}
if (Objects.equals(timer.getInfo(), "at3AM"))
{
// Call Something else
}
}
}
@Lock(READ)- areus