This week's book giveaway is in the General Computing forum. We're giving away four copies of Arduino in Action and have Martin Evans, Joshua Noble, and Jordan Hochenbaum on-line! See this thread for details.
I have implemented ejbTimeout in my MDB. I want the ejbTimeout to be called only once when the timeout happens but it is called at regular intervals.
Below is the code how i am creating a Timer TimerService ts = this.ctx.getTimerService(); long timerValue = scheduledTime.getTimeInMillis(); Timer timer = ts.createTimer(timerValue, "mytimer");
Tried this with a sample application and worked fine for me:
Sent 1 message to the queue on which this MDB was listening. The timer got triggered after 20 seconds and only once for this one message. Is your code similar or do you have something else?
nandkishor rao
Ranch Hand
Joined: May 24, 2006
Posts: 53
posted
0
this My mdb has to start by itself so when my application is deployed it calls the ejbCreate(), from there I am posting a message to the MDB itself and that is how my mdb gets the first message. After receiving the message in onMessage(), it sets my timer value. So my ejbTimeout method is called but the problem is it is called more than once. In my ejbTimeout I have implemented my buisness logic which is calling some helper java classes to insert data into database. But after inserting some rows into database it giving me a EJBException: transaction timed out after 34 secs. After this exception is thrown, ejbCreate() and ejbTimeout() is called several times , don't know why,Is it because of the exception???
when my application is deployed it calls the ejbCreate(), from there I am posting a message to the MDB itself and that is how my mdb gets the first message
Any reason why you are doing this? The MDB publishing a message to itself.
transaction timed out after 34 secs. After this exception is thrown, ejbCreate() and ejbTimeout() is called several times , don't know why,Is it because of the exception???
That's the problem. Since the transaction is rolled back, the message is being redelivered and looks like on redelivery of the message a new instance of the MDB is created and hence the ejbCreate method is being called again.
nandkishor rao
Ranch Hand
Joined: May 24, 2006
Posts: 53
posted
0
I have taken care that the message to MDB itself should be delivered once and the message is getting consumed.
I am putting my code of ejbCreate() Here counter is a static variable in some other class /** * This method is required by the EJB Specification. */ public void ejbCreate() { log.debug("ejbCreate() of RcuTimerMDB - ejbCreate called"); if (RcuAfmDao.COUNTER == 0) { this.subject = "RCUTimerToRunAt2PM"; postMessage(); RcuAfmDao.COUNTER++; } } private void postMessage() { // post a dummy message to the same queue bean JMSQueueDispatcherInterface dispatcher = (JMSQueueDispatcher) ApplicationContextManager.getApplicationContext() .getBean("jMSQueueDispatcher"); log.debug("inside postMessage" + dispatcher.toString()); dispatcher.dispatchToQueue(JMSQueueCommon.RCU_TIMER_QUEUE, new String(this.subject)); log.debug("posted Message to: " + JMSQueueCommon.RCU_TIMER_QUEUE + "SUBJECT: " + this.subject);
Nandkishor, as per the specs whenever the transaction in the onMessage method gets rollbacked (maybe due to an exception), the server will redeliver the message (upto the redeliverylimit value) to the MDB. Effectively, this means that the onMessage method will be called that many times (you can verify this by adding some System.out.println statements in that method) and as a result the createTimer code will be executed repeatedly.
nandkishor rao
Ranch Hand
Joined: May 24, 2006
Posts: 53
posted
0
Thanks man, I think thats the problem. Anyways I am putting my onMessage code here. May be if there i anything more which you can find out.
public void onMessage(Message msg) { final ObjectMessage om = (ObjectMessage) msg; log.debug("Message received" + om); try { String message = (String) om.getObject(); Calendar scheduledTime; if (message.equals("RCUTimerToRunAt2PM")) { scheduledTime = Calendar.getInstance(); scheduledTime.set(Calendar.HOUR_OF_DAY, 0); scheduledTime.set(Calendar.MINUTE, 0); scheduledTime.set(Calendar.SECOND, 0); scheduledTime.set(Calendar.MILLISECOND, 0); // Changing for now to RUN scheduledTime.add(Calendar.HOUR_OF_DAY, +17); scheduledTime.add(Calendar.MINUTE, +55); log.debug("Setting the scheduler to run at 2 PM SCHEDULED TIME SET : " + scheduledTime.get(Calendar.HOUR_OF_DAY)); log.debug("Setting the scheduler to run at 2 PM " + scheduledTime.get(Calendar.MINUTE));
Calendar currentTime = Calendar.getInstance(); long timerValue = 0; if (scheduledTime.getTimeInMillis() > currentTime.getTimeInMillis()) { // if (scheduledTime.get(Calendar.HOUR_OF_DAY) > // currentTime.get(Calendar.HOUR_OF_DAY)) { timerValue = scheduledTime.getTimeInMillis() - currentTime.getTimeInMillis(); log.debug("Timer value set to read PACS CSV at 2 PM, TIMER VALUE: " + timerValue + " AND SCHEDULED TIME: " + scheduledTime.get(Calendar.HOUR_OF_DAY)); } else { int todaysDay = currentTime.get(Calendar.DAY_OF_WEEK); scheduledTime.set(Calendar.DAY_OF_WEEK, todaysDay + 1); scheduledTime.set(Calendar.HOUR_OF_DAY, +14); scheduledTime.set(Calendar.MINUTE, 0); scheduledTime.set(Calendar.SECOND, 0); scheduledTime.set(Calendar.MILLISECOND, 0);
timerValue = scheduledTime.getTimeInMillis(); log.debug("Timer value set to read PACS CSV tomorrow at 2PM, TIMER VALUE: " + timerValue + " AND SCHEDULED TIME: " + scheduledTime.get(Calendar.HOUR_OF_DAY));
String day; switch (scheduledTime.get(Calendar.DAY_OF_WEEK)) { case Calendar.SUNDAY: day = "SUNDAY"; break; case Calendar.MONDAY: day = "MONDAY"; break; case Calendar.TUESDAY: day = "TUESDAY"; break; case Calendar.WEDNESDAY: day = "WEDNESDAY"; break; case Calendar.THURSDAY: day = "THURSDAY"; break; case Calendar.FRIDAY: day = "FRIDAY"; break; case Calendar.SATURDAY: day = "SATURDAY"; break; default: day = "UNKNOWN"; break; } log.debug("Scheduled Day: " + day); this.subject = "RCUTimerToRunAt2PM"; log.debug("subject value :-" + this.subject); } TimerService ts = this.ctx.getTimerService(); // Here TimerName will be this.subject Timer timer = ts.createTimer(timerValue, this.subject); }
nandkishor rao
Ranch Hand
Joined: May 24, 2006
Posts: 53
posted
0
Please help me out
I am getting this exception while the ejbTimeout() is called in this I have implemented my buisness logic which is working very fine but after sometime i am getting this exception . As far as I know the default timeout for MDB is 1 day then why is the transaction timeout.
Unexpected exception while enlisting XAConnectionjava.sql.SQLException: Transaction rolled back: Transaction timed out after 32 seconds BEA1-553C4F1FEDDAA91F05EC