Transaction timeouts in MDB migration from JBoss 4.2.2 to 7.1.1-Final
firebet99 Jan 30, 2013 10:15 AMHi - I'm new to JBoss 7 and have recently undergone a solo effort to upgrade a large legacy application from JBoss 4.2.2 to 7.1.1-Final. I'll admit it wasn't straightforward but for the most part it has been successful. There are a few issues that I've struggled with though, one of which I'd like to discuss here.
I spent most of yesterday trying to track down an issue with timeouts and rollback in a number of MDBs that I have migrated. I followed a few different EJB 2.x -> 3.x migration articles and have a MDB setup that uses purely Bean-managed transactions. The MDBs generally kick-off long-running async processes from a servlet-based application to allow us to continue without waiting for response from the processes (which write to log tables). For example, the onMessag() method may start a Grid-enabled process that may take up to 30-40 mins to return a result or may start a series of large data updates using DAOs that control their own transactions, and the onMessaga() method blocks until the result returns.
In JBoss 4.2.2 these MDBs always worked fine and I did not see a timeout set explicitly anywhere in the ejb xml config. However after migration I found that processes taking longer than 5 min (300 seconds) appeared to be rolled-back by the Arjuna TX 'reaper' process, which was causing havoc in the app as the messages were then being re-tried causing duplicate results (fortunately it's only in QA for now!) After creating a test case with a sleep() method and trying various methods of increasing the timeout using annotations in the class - (none of which appeared to work) - I finally tracked the issue down to the transactions subsystem entry <coordinator-environment default-timeout="300"/> thanks to this post: https://community.jboss.org/thread/203599
Changing this setting to a higher value allows the processes to complete without Arjuna timing them out.
My questions are:
1) If I specify the class as bean-managed @TransactionManagement(TransactionManagementType.BEAN) and @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) why is Arjuna still timing out the onMessage() method? Does the system process the onMessage() method inside a transaction regardless of the class/method annotations specified?
2) If the MDB does timeout and rollback, how can I prevent the message being re-tried? The Use-Case is to try the operation once and notify the user if something goes wrong via log tables - but not to retry unless the user explicitly tries the operation again.
3) I don't really like the workaround of increasing the general default timeout as I'm concerned about effects on other processes. The underlying DAOs control transaction management but I'd like to configure the onMessage() timeout on a per-MDB basis to make it clear in the code that the process may take a long time to complete. Is this possible? The timeout annotation (org.jboss.ejb3.annotation.TransactionTimeout) value seems to get ignored - presumably something to do with the TransactionAttributeType I am setting? Do I need to implement UserTransaction.setTransactionTimeout()? I've seen various posts pointing out issues with that approach too. Right now, I don't declare UserTransaction in any of my MDBs - only @Resource MessageDrivenContext, which is only invoked in the case of a JMSException (I call setRollbackOnly()) but not if any other kind of Exception occurs.
Any suggestions for best-practise given my scenario? I'm happy to post code examples if necessary.
Many thanks.