You are essentially asking for the application server to "look ahead" at a bean's potential use of a JDBC connection factory and decide whether or not to execute the bean based on if it thinks the connection factory will have sufficient connections. As you can imagine, no such feature exists.
As you noted, the connection pool can dynamically grow and shrink based on demand. If the growth of the pool out-paces your database's capacity then lower the maximum pool size. If the EJBs need more connections than the pool contains then lower the bean pool size(s). This is all a balancing/tuning exercise.
Also, the "No ManagedConnections available within configured blocking timeout" issue is simply a matter of the connection pool being out of connections. It shouldn't de-stabalize the application server or the application (assuming it handles the exception properly). When requesting access to a shared resource the application should always handle the scenario where that resource is not available.
- So a solution might be not to use MDBs to get messages and rather use some sort of distributer that will query around both the queues and the connection pool and create consumers on the fly - or something like that.
kind of a vauge idea - but if this is something i want to implement
- another direction I thought about - i can add to my MDBs a method with @PreActivate annotation that will run in an endless loop until it will find that there are available connections
- of course for the first time it might recieve a transaction timedout, but it might make it in the retry
does this sound sane?
1 of 1 people found this helpful
It sounds to me like you're ready to throw away the power and flexibility of container-managed resources (i.e. MDBs) so that you can avoid a few messages on your DLQ every once in awhile. That doesn't sound sane to me.
In my opinion the first option is to get a database that can handle the load from the application server. This shouldn't be hard. There are a number of good, open-source databases that could suffice.
The next option is just to deal with the messages on the DLQ. The DLQ is just a normal JMS destination. You could have a EJB timer run every so often to inspect the DLQ and move them back to their original destination or whatever is necessary.
thanks - I am actually writing now this kind of code for the DLQ - I guess I will just need to make sure that the errors won't be thrown to the log so my customers wouldn't freak out
1 of 1 people found this helpful
To prevent errors being printed in the log you simply need to handle RuntimeExceptions appropriately (which you should already be doing, but probably aren't based on your comment). Please note, according to the JMS 1.1 specification (section 4.5.2) it isn't appropriate to throw a RuntimeException from onMessage(). Furthermore, a RuntimeException thrown from any method of the message-driven bean class (including a message listener method and the callbacks invoked by the container) results in the transition to the 'does not exist' state which means that the container has throw that instance of the MDB away and create a new one. The proper way to deal with RuntimeExceptions in an MDB is to catch them and if you want the message to be redelivered or potentially sent to a DLQ, invoke setRollbackOnly() on the MDB's context if you're running in a transaction (which all MDBs do by default).