Circumvent Nested Transaction Issues in Tapestry-5.x

Ajax component events may be wrapped in a transaction as I pointed out in “Transaction Handling for Ajax Components in Tapestry-5.x“. But on some occasions an Ajax component event is surrounded by a component event. So the code in the ControllerUtil of article “Transaction Handling in Tapestry5” will lead to ‘transaction already active’ problems, since we try to begin a transaction in the nested ajax component event although there is already an active transaction attached to the current thread. We can overcome this situation by checking, whether an active transaction is present and begin/commit/rollback a new transaction iff not. This behavior is similar to the default transaction attribute REQUIRED in Java EE.

Here is the new code in ControllerUtil:

public static UserTransaction beginTransaction() throws
		SystemException, NamingException, javax.transaction.NotSupportedException {
	UserTransaction tx = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction");
	// Start a transaction only if it is not already active.
	if(tx.getStatus() != Status.STATUS_ACTIVE) {
		tx.begin();
		return tx;
	}
	return null;
}
public static void commitTransaction(UserTransaction tx) throws
		IllegalStateException, RollbackException, HeuristicMixedException,
		HeuristicRollbackException, SystemException, javax.transaction.RollbackException {
	if (tx != null) {
		tx.commit();
	}
}
public static void rollbackTransaction(UserTransaction tx) throws
		IllegalStateException, SystemException {
	if (tx != null) {
		tx.rollback();
	}
}

Leave a Reply

Your email address will not be published. Required fields are marked *