I wrote a XA transactinal connection factory which is injected into a stateless session bean. This factory is Unshareable. When this bean is used for the first time everything is OK, i.e. a connection is retrieved from this factory and it is enlisted in the transaction manager. At the end of bean's transactional method this connection is put back to the pool and delisted from the transaction manager.
But when this bean is used for the second time, there is an associated session context with a list of resources. In this list, there exists a resource handle with the connection which was used in the previous invocation of this bean. Before the body of the invoked method is executed, this resource handle is enlisted in a new transaction, although this connection is not yet acquired from the factory. It will be done in this body (I think that it is some optimization, which assumes that the same connection will be obtained from the pool once more time).
But it is a trap! Another concurrent instance of bean can get this enlisted connection before the above mentioned instance of bean do it. This connection (resource handle with this connection) has the "enlisted" flag set to true, and it is not (and of course shouldn't be) enlisted once more time. So this connection takes a part in a separate transaction than it is used.
In the method getResourceFromPool of the class com.sun.enterprise.resource.pool.ConnectionPool, there is even the following comment:
But there is no verification of this flag anywhere. Even in the method ds.getResource(), where I think it should be (ds is an instance of the class RWLockDataStructure).
This "enlisted" flag should be checked in the method getResourceFromPool (especially that this method is invoked from the method getUnenlistedResource), or no caching of the previous resource handles should be done in the session context of the bean. Why such caching is done - getting a connection from the pool is done independently of this caching?