Transaction Status.STATUS_ROLLEDBACK
huuskart Jul 10, 2008 7:41 AMWhen a transaction timeout or some other unexpected situation occurs, the new JBoss transaction manager (in JBoss 4.2.1.GA) marks the transaction into state Status.STATUS_ROLLEDBACK.
I would argue, from the point of view of bean managed transactions EJB session application code, that this is not quite productive. (note that this is almost the same as JBAS-4481, but this issue concerns application code that wants to clean up a transaction, so that it may try to begin again.)
Trying to code a BMT EJB session, that is able to recover from transaction errors, and reading javax.transaction.Status javadocs, I would never expect to see Status.STATUS_ROLLEDBACK. The only status codes my application code would expect (in case of single resource only) are STATUS_ACTIVE, STATUS_NO_TRANSACTION and STATUS_MARKED_ROLLBACK. Even JTA javadocs suggest this, saying that in stead of STATUS_ROLLEDBACK, NO_TRANSACTION should be returned.
JBoss TM further complicates this issue, because trying to call rollback() on transaction marked STATUS_ROLLEDBACK just throws an IllegalStateException. Thus there is no way an application code can "gracefully" handle the error situation.
Previously my tx handling code looked more or less like this:
UserTransaction tx = sessionContext.getUserTransaction(); try { tx.begin(); work(); tx.commit(); } finally { if ((tx.getStatus() == STATUS_ACTIVE) || (tx.getStatus() == STATUS_MARKED_ROLLBACK)) tx.rollback(); }
Now this needs to change to:
UserTransaction tx = sessionContext.getUserTransaction(); try { tx.begin(); work(); tx.commit(); } finally { if ((tx.getStatus() == STATUS_ACTIVE) || (tx.getStatus() == STATUS_MARKED_ROLLBACK)) tx.rollback(); else if (tx.getStatus() == STATUS_ROLLEDBACK) { try { tx.rollback(); } catch (IllegalStateException ex) { /* ignore */ } } }
That is the only way to get the tx back to state NO_TRANSACTION, so that I can call begin() on the transaction again.
Reading JBAS-4481, I get the impression that it is for some reason almost impossible for current implementation to mark the transaction into status NO_TRANSACTION in case of timeout. Fair enough (not really), but could the implementation at least refrain from throwing the IllegalStateException if I rollback a transaction marked STATUS_ROLLEDBACK.