@MessageDriven transactions and delivery semantics

What is the best way to accomplish the following?

  • @MessageDriven bean does some database work
  • on failure, I want to cancel the DB transaction
  • but I also want the JMS NOT message to be re-added, i.e. do not try again.

I can come up with several ways that might work. Are there others, and which is better?

  • use @TransactionManagement(type=BEAN) and UserTransaction , and explicitly roll back after catching exception. eg:.

    catch (Exception e) { e.printStackTrace(); utx.rollback(); }

  • Use container-driven transactions, specify @TransactionAttribute(value=NOT_SUPPORTED) on onMessage and then delegate database activity to a particular method using @TransactionAttribute(value=REQUIRED) .

  • Leave the transaction processing on your own and reconfigure the retry property on the server. I am using Glassfish 3.1.1 and I am not quite sure how to install it.

  • Leave everything alone and explicitly check the message for re-delivery in the body of onMessage and exit it if it is re-delivered. ( message.getJMSRedelivered() ?)

What works well there? Is there a standard / best way to solve this problem?

+8
glassfish glassfish-3 jms message-driven-bean
source share
2 answers

The easiest and most portable approach is to use @TransactionAttribute(value=NOT_SUPPORTED) on onMessage() when you specify and move the database to another bean using @TransactionAttribute(REQUIRES_NEW)

Be careful with a separate method as this will not work. In the JMS MDB, the onMessage() method is the only method that @TransactionAttribute can be used @TransactionAttribute .

+8
source share

Personally, I never do any work in MDB, but immediately send a bean session to the (nested) one.

In this bean the DB works. It either starts a new transaction, or I exit any exception from the bean and write it down (but do not let it run, so there is no re-delivery).

It also has the advantage that business logic is easy to reuse from other places.

+2
source share

All Articles