IronJacamar

Transactional ConnectionEventListener tracking

The Java EE Connector Architecture has a concept called a ConnectionEventListener which is the mechanism that a resource adapter notifies the ConnectionManager that a connection handle isn't longer in use, or had an error occur on it.

The ConnectionManager uses these notifications to know when a ManagedConnection can be returned to the pool, since the ConnectionEventListener keeps track of the connection handles registered and unregistred.

Another dimension comes into play when the ManagedConnection is enlisted in a transaction, e.g. when the resource adapter is deployed with either LocalTransaction or XATransaction as its transaction setting.

The XAResource instance associated, either through the IronJacamar container in the case of LocalTransaction or the instance directly attached to the ManagedConnection in the case of XATransaction is enlisted on the active transaction through the tx.enlistResource(xaResource) method call, and the ManagedConnection is "scoped" to the transaction itself.

However, that present a problem when a connection handle is used across transactional boundaries, like

// UserTransaction instance bound to 'ut', and DataSource instance bound to 'ds'
Connection c = null;

// Transaction #1
ut.begin();
c = ds.getConnection();
ut.commit();

// Transaction #2
ut.begin();
c.close();
ut.commit();

because at the end of Transaction #1 the associated XAResource is delisted from the transaction, but the ManagedConnection can't be returned to the pool, as there is still a connection handle associated. This means that usage of the connection handle in Transaction #2 can't be determined in a transactional context, since there is no XAResource associated with Transaction #2 . The c.close() will allow the ManagedConnection instance to be returned to the pool, but not on transactional boundary itself.

This scenario is due to application usage errors, so we should detect and highlight the problem to the developers.

There is a new deployment attribute called tracking which can be used to enable tracking of the transactional ConnectionEventListener over the transactional boundaries.

The IronJacamar default setting will be to only report that it has detected the problem, and have therefore destroyed the associated ManagedConnection instance, as it can't be trusted anymore.

11:31:32,952 ERROR [TxConnectionListener] IJ000315: Pool TxLog has 1 active handles

By setting tracking to true you will get a full trace of where the connection handle was allocated, and where the transaction boundary ended

11:31:32,952 ERROR [TxConnectionListener] IJ000315: Pool TxLog has 1 active handles

11:31:32,953 ERROR [TxConnectionListener] IJ000316: Handle allocation: TxLogConnection@520c87f3[mc=TxLogManagedConnection@7f0eb91e[txState=3B8]]: java.lang.Exception at org.jboss.jca.core.connectionmanager.listener.AbstractConnectionListener.registerConnection(AbstractConnectionListener.java:281) at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.registerAssociation(AbstractConnectionManager.java:880) at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.allocateConnection(AbstractConnectionManager.java:590) at org.jboss.jca.core.tx.rars.txlog.TxLogConnectionFactoryImpl.getConnection(TxLogConnectionFactoryImpl.java:80) at org.jboss.jca.core.connectionmanager.listener.AcrossTransactionTestCase.testBase(AcrossTransactionTestCase.java:197) at org.jboss.jca.core.connectionmanager.listener.AcrossTransactionTestCase.testXA(AcrossTransactionTestCase.java:254)

11:31:32,955 ERROR [TxConnectionListener] IJ000317: Transaction boundary: java.lang.Exception at org.jboss.jca.core.connectionmanager.listener.TxConnectionListener$TransactionSynchronization.afterCompletion(TxConnectionListener.java:1028) at org.jboss.jca.core.connectionmanager.transaction.TransactionSynchronizer.invokeAfter(TransactionSynchronizer.java:397) at org.jboss.jca.core.connectionmanager.transaction.TransactionSynchronizer.afterCompletion(TransactionSynchronizer.java:343) at org.jboss.jca.core.tx.vts.TransactionImpl.finish(TransactionImpl.java:402) at org.jboss.jca.core.tx.vts.TransactionImpl.commit(TransactionImpl.java:99) at org.jboss.jca.core.tx.vts.TxRegistry.commitTransaction(TxRegistry.java:79) at org.jboss.jca.core.tx.vts.UserTransactionImpl.commit(UserTransactionImpl.java:115) at org.jboss.jca.core.connectionmanager.listener.AcrossTransactionTestCase.testBase(AcrossTransactionTestCase.java:199) at org.jboss.jca.core.connectionmanager.listener.AcrossTransactionTestCase.testXA(AcrossTransactionTestCase.java:254)

For XATransaction with interleaving scenarios the error code IJ000318 will be reported.

By setting tracking to false you will get the old behavior, where the ManagedConnection will be valid across the transactional boundaries, but only enlisted during the first transaction.

The IronJacamar community hopes that this new feature will help developers to find application code, which has been assuming certain conditions that weren't valid.