This a real simple issue I guess but I am not able to figure why it happens so though. I have an implementation of an EJB timer which uses @Singleton annotation i.e. a singleton timer.
I have set it to run after every 5 mins. The code looks something like this :
@Singleton
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class Scheduler {
private static final double timerVar = Math.random() * 33;
static Logger logger = Logger.getLogger("Scheduler");
@Schedule(second = "*", minute = "*/5", hour = "*", persistent = true)
public void doWork() {
logger.log(Level.INFO, "timer value for this session : " + timerVar);
}
}
When the process runs it executed 10 scheduler instances simultaneously in a gap of 1 sec i.e.
(EJB default - 1)
(EJB default - 2)
(EJB default - 3)
(EJB default - 4)
and so on. When I put a lengthy operation within the code, the (EJB default - 1)
is not complete and when (EJB default - 2)
tries to execute it gives me an error saying:
JBAS014373: EJB 3.1 PFD2 4.8.5.5.1 concurrent access timeout on org.jboss.invocation.InterceptorContext$Invocation@1b83ad52 - could not obtain lock within 5000 MILLISECONDS
First, how can I avoid multiple EJB scheduler instances to be executed at a time? Second, what is the deal with "could not obtain lock within 5000MILLISECONDS" and how can I avoid it?
For the timeout error I get, I found there are a lot of tickets in JBOSS queue as mentioned here.
EDIT
Added the code in the latest comment so it's readable:
@Tushar-46835, could you expound upon your solution, maybe show us the snippet of what you did? – rtcarlson Oct 2 '14 at 20:12
@rtcarlson : Here is the code snippet which fixed my issues:
@Resource
TimerService timerService;
@Schedule(persistent = false, minute = "/30", hour = "")
public void checkQueueState() {
dt = new DataAccessFactory();
excvo = dt.canExecute();
dt = null;
available = excvo.isExecuteReady();
if (available) {
timerService.createSingleActionTimer(new Date(), new TimerConfig(null, false));
}
}
@Timeout
private void generateReport(Timer timer) {
logger.info("!!--timeout invoked here " + new Date());
}
First, how can I avoid multiple EJB scheduler instances to be executed at a time?
You are creating persistent timers. So after specified interval, it will be creating new ones & enqueueing them, waiting for the previous one to finish its execution.
I presume, after you restart, all enqueued timers have timed-out & multiple instances will be created by the server as they are persistent.
Second, what is the deal with "could not obtain lock within 5000MILLISECONDS" and how can I avoid it?
It's singleton, all method have lock-type write by default, so only one thread will be executiing at a time. Therefore others will get timeout exception/ could not obtain lock etc. as you said, there is a long running process.