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.