What's the best way to accomplish the following?
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?
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.
Personally I never do any work in the MDB, but dispatch immediately to an (injected) session bean.
This bean then does the DB work. It either starts a new transaction, or I catch any exception from the bean and log it (but don't let it propogate, so no redelivery).
This also has the advantage that the business logic is easly reusable from other places.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With