• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • paul wheaton
  • Ron McLeod
  • Devaka Cooray
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
  • Paul Clapham
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:

Queue - Unlimited Attempts At Delivery

 
Ranch Hand
Posts: 226
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

I have an EJB3 MDB listening to a queue, running in GlassFish v3. I want it to perform a function, but if it fails, to retry later. I also want it to keep retrying until it succeeds, and I am not worried about poison messages.

So, using Container Managed Transactions (CMT) within my MDB, and the default transaction type of 'Required', I can have the context injected, and on failure I can use the setRollbackOnly method to rollback the transaction. This will put the message back on the queue for another try later.

However, I have two questions.
- I can't find it in the spec, but I can find references to Activation Config parameters on Internet searches. For example - endpointExceptionRedeliveryAttempts. For example, here and here on page 356. I can't work out whether these are global across application servers (cause it is in the spec and I've missed it), specific to "Sun Java System Message Queue", or applicable to Glassfish. This would suggest that it was applicable to Glassfish. What I also can't work out is what I set it to if I want an unlimited number of attempts, as the default of 6 is no good (-1 seems an obvious choice but I can't find it any of the docs). A list of all of these Activation Config parameters, their acceptable values and what they do would be very helpful, but I just can't find it.

- Secondly, if I wanted a delay between attempts, is there a config value for this? For example, an attempt fails, but I want to leave it 30mins before trying again. I can put a delay in the MDB but that's not really the right place for it.

Hope someone can help,

Thanks,

MG
 
Ranch Hand
Posts: 2198
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi!
I have been thinking about this today but still not been able to come up with a solution that I feel entirely content with.
An outline of the ideas I have are:
- Use an additional queue, in which failed attempts are inserted.
- Failed attempts are timestamped.
- Periodically, perhaps using an EJB timer, poll the failed attempts queue for messages that are old enough to be retried.
Insert such messages in the original queue.
Since you want to wait until a certain period of time has elapsed and, if a message is not old enough, leave it in the queue to age some more, using an MDB to get the messages from the queue may not be a good idea.

Using the above way, you avoid a failed message blocking the way for other messages. This may or may not be a problem in your system - I do not know enough about it to be able to tell.
The fact that MDBs seem to be unable to roll back a received message unless throwing an exception causes problems in both your example and the solution outline I have been thinking of.
Best wishes!
 
Ranch Hand
Posts: 104
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
JMS spec does not mention anything about the redelivery. It is entirely up to the JMS server. Please refer to this article about the JMS message redelievery
 
Mark Garland
Ranch Hand
Posts: 226
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Ivan and k space,

Ivan Krizsan wrote:
I have been thinking about this today


Thanks!

Ivan Krizsan wrote:
- Periodically, perhaps using an EJB timer, poll the failed attempts queue for messages that are old enough to be retried.


I like this idea. If a message fails, I could bung it on the 'broken queue', then have an EJB timer periodically check the queue and retry anything on there. This is quite a neat idea.

Ivan Krizsan wrote:
The fact that MDBs seem to be unable to roll back a received message unless throwing an exception causes problems in both your example and the solution outline I have been thinking of.


I'm not sure that this is quite right. You can simply use the context and call setRollbackOnly(), and the container will do the rest for you. I'll post some code in a mo.

k space wrote:JMS spec does not mention anything about the redelivery. It is entirely up to the JMS server. Please refer to this article about the JMS message redelievery


Great article! Thanks. Sadly it does not mention about Glassfish, but at least I know that these things are queue/application server specific.

Thank you both very much for your efforts - much appreciated!

MG
 
Mark Garland
Ranch Hand
Posts: 226
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi all,

Here is some of the code I managed to get working. Glassfish keeps endlessly and instantly retrying to deliver a failed message - exactly the behaviour I wanted.
Notice how I achieved the delay by getting the thread to sleep for a bit during failure scenarios - this doesn't block other messages because the EJB can be multi-threaded.
Also notice the use of context.setRollbackOnly(); to bounce a failed message.
Poison messages aren't catered for here, but as it's only a home project I'm not too concerned.

Hope this helps someone,

Comments welcome.

MG


 
Ivan Krizsan
Ranch Hand
Posts: 2198
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi!

Mark Garland wrote:

Ivan Krizsan wrote:
The fact that MDBs seem to be unable to roll back a received message unless throwing an exception causes problems in both your example and the solution outline I have been thinking of.


I'm not sure that this is quite right. You can simply use the context and call setRollbackOnly(), and the container will do the rest for you.


Hehe, you must mean that I am wrong!
Thanks for that piece of information - yes I definitely need to have a closer look at MDBs.
Thanks also for your code example - I will definitely "play around" with it some in a close future.
Best wishes!
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic