MessageDriven bean, pause when resource is not available

I'm new to message driven beans but I'd like to use one.

The purpose of the bean is to do sg in the database.

However, the db will not be always available. In such case, I'd like to  have it to wait until it becomes available again.

I know that I could check if it is available and thread.sleep if not but I wonder if there is a better way to do it.
zsoltvinczeAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
cjjcliffordConnect With a Mentor Commented:
yup queue size, if JMS queue fills up, etc. pretty sure this can be configured (obviously there is a theoritical limit to the queue length, so there must be a way to config. it - I've never run into upper lengths though....)

If clients "must not wait", then how valid is it that the MDB wait before flushing to DB? Surely if client can't wait, then it is safer to raise an exception back to them that the DB couldn't be written to (if they finish, and DB not available, and MDB waits, and eventually DB work fails, the client will never know... if this is acceptable, then make queue lengths as long as possible (obviously, you'll want to use persistent queues, otherwise a re-start of the JMS provider will cause pending messages to disappear!)

One thing about a timer is Timer runs TimerTask on seperate threads, so once a TimerTask is scheduled, control is returned back to the calling code. If you are going to use this in the onMessage(), then every message will cause a TimerTask to be added to the timer - causing a possible hole if the application is restarted/bounced! (isn't starting a new thread in EJB land a no-no?) Doing a while( noDBConnection ) { Thread.sleep( 2000 ); } in the onMessage() will (eventually, once all deployed bean instances have entered onMessage()) wait, causing messages to backup in JMS (persisted), which will then get processed when DB connection is available (to be really sure about restarts etc, use manual message acknowledgement, and ACK only after successful writing to DB, otherwise the message that caused the Thread.sleep() will be lost if the application fails before its written....)
0
 
TimYatesCommented:
I can't think of a better way... :-(
0
 
TimYatesCommented:
Instead of Thread.sleep (which will freeze your entire MDB), why not start a TimerTask to perform the function when the db is awake again?
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
TimYatesCommented:
> why not start a TimerTask

why not start a repeating TimerTask

Task
1.  Is DB awake?
2.  Yes, perform action on database and close timer
3.  No, end this loop, and repeat to 1 in a set number of seconds
0
 
CEHJCommented:
Isn't it more appropriate for what's sending the bean the message to do the waiting?
0
 
zsoltvinczeAuthor Commented:
I cannot see why a Timer is better then the Thread.sleep. Neither of them will freeze anything. I'm running it under jboss by the way. Would the behaviour change on a diff. app server?

Here is my simple test:

MessageBean1 : Sleeps for 2 minutes in onMessage
MessageBean2 : Sleeps for 5 seconds in onMessage
Queue 1 for Bean1
Queue 2 for bean2

Both writes to the console so I can see what is happening.

From the client: Send 30 messages to Queue1.
While it is happening, I can see that the server is picking up the messages and the Sleep function takes control. The server picks up 15 messages before proceeding with the next ones. (as per server setting)

At this stage, nothing is really happening, 15 messages are being executed and they are all asleep.

Now, I send a bunch of messages to Queue2 and the server picks them all up and their onMessage runs.

Some time after, Bean1 beans wake up and the server executes the next based on the queued messages.

So to me it looks ok but I still have two questions:
1. (as the original) Isn't there a built in functionality that would turn off the processing of the messages, with other words they would automatically get queued but not processed.

2. If the answer for Q1 is NO, would my little test work differnently on a diff app server?
0
 
zsoltvinczeAuthor Commented:
re:CEHJ's comment
The client(s) have no idea what the bean is supposed to do and they have no access to the db. Plus they do not care, they just want to send the message.
0
 
CEHJCommented:
ok ;-)
0
 
cjjcliffordCommented:
I would take care with using a TimerTask, and returning from onMessage(), as this will remove the object from the queue, especially if you are using AUTOACK.

What's the problem with waiting inside onMessage() if resources are not available - once all deployed MDBs are waiting as such, the queue will take the backlog of requests from clients, and if configured, the clients will eventually wait on submission, etc. Surely the MDB's purpose is to process the incoming message and perform the DB related task, nothing more, so causing this to block waiting for resources is not a problem... if there is more operations than that present in the MDB, which can proceed without the DB operations, then this could be split further, with one MDB handling these operations, then placing the message onto another queue, for the DB-only MDB for processing...

Cheers,
C
0
 
zsoltvinczeAuthor Commented:
All right, that confirms that what I was thinking, such us coding the wait, was right.

I'm still not sure however what the diff is between sleep and timer.

In terms of memeory it seems to be about the same.

What I do not get is the "and if configured, the clients will eventually wait on submission, etc." line.

Does it refer to some "queue size" server parameter? Can you explain this please?

Bottom line is: Clients mustn't wait and must be able to complete their transaction.
0
All Courses

From novice to tech pro — start learning today.