Search code examples
glassfishjmsglassfish-3ejb-3.1message-driven-bean

@MessageDriven transactions and redelivery semantics


What's the best way to accomplish the following?

  • @MessageDriven bean does some work on database
  • on failure, I want to roll back the DB transaction
  • but I also want the JMS message NOT to be redelivered, i.e., don't re-try.

I can think of a few ways that might work. Are there any others, and which is the best?

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

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

  • Use container-managed transactions, specify @TransactionAttribute(value=NOT_SUPPORTED) on onMessage and then delegate DB activity to a separate method with @TransactionAttribute(value=REQUIRED).

  • Leave the transaction handling alone and re-configure the retry property in the server. I'm using Glassfish 3.1.1, and I'm not exactly sure how to set this.

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

What has worked well out there? Is there a standard/best-practice way for dealing with this?


Solution

  • Simplest and most portable approach is use @TransactionAttribute(value=NOT_SUPPORTED) on onMessage() as you state and to move the DB work to another bean with @TransactionAttribute(REQUIRES_NEW)

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