/** * Gets connection listener instance associated with transaction. This method is package protected * beacause it is intended only for test case use. Please don't use it in your production code. * * @param trackByTransaction transaction instance * @param mcp the managed connection pool associated with the desired connection listener * @return connection listener instance * @throws ResourceException Thrown if an error occurs */ ConnectionListener getTransactionOldConnection( Transaction trackByTransaction, ManagedConnectionPool mcp) throws ResourceException { TransactionSynchronizationRegistry tsr = getTransactionSynchronizationRegistry(); Lock lock = getLock(); try { lock.lockInterruptibly(); } catch (InterruptedException ie) { Thread.interrupted(); throw new ResourceException(bundle.unableObtainLock(), ie); } try { // Already got one ConnectionListener cl = (ConnectionListener) tsr.getResource(mcp); if (cl != null) { if (trace) log.tracef("Previous connection tracked by transaction=%s tx=%s", cl, trackByTransaction); return cl; } return null; } finally { lock.unlock(); } }
/** * Gets new connection listener if necessary instance with transaction. This method is package * protected beacause it is intended only for test case use. Please don't use it in your * production code. * * @param trackByTransaction transaction instance * @param mcp pool instance * @param subject subject instance * @param cri connection request info * @return connection listener instance * @throws ResourceException ResourceException */ ConnectionListener getTransactionNewConnection( Transaction trackByTransaction, ManagedConnectionPool mcp, Subject subject, ConnectionRequestInfo cri) throws ResourceException { // Need a new one for this transaction // This must be done outside the tx local lock, otherwise // the tx timeout won't work and get connection can do a lot of other work // with many opportunities for deadlocks. // Instead we do a double check after we got the transaction to see // whether another thread beat us to the punch. ConnectionListener cl = mcp.getConnection(subject, cri); if (trace) log.tracef( "Got connection from pool tracked by transaction=%s tx=%s", cl, trackByTransaction); TransactionSynchronizationRegistry tsr = getTransactionSynchronizationRegistry(); Lock lock = getLock(); try { lock.lockInterruptibly(); } catch (InterruptedException ie) { Thread.interrupted(); throw new ResourceException(bundle.unableObtainLock(), ie); } try { // Check we weren't racing with another transaction ConnectionListener other = (ConnectionListener) tsr.getResource(mcp); if (other != null) { mcp.returnConnection(cl, false); if (trace) log.tracef( "Another thread already got a connection tracked by transaction=%s tx=%s", other, trackByTransaction); cl = other; } // This is the connection for this transaction cl.setTrackByTx(true); tsr.putResource(mcp, cl); if (trace) log.tracef( "Using connection from pool tracked by transaction=%s tx=%s", cl, trackByTransaction); return cl; } finally { lock.unlock(); } }