new ConnectionKey(factory, (cri instanceof GenericConnectionRequestInfo) ?
((GenericConnectionRequestInfo)cri).getManagedConnectionPartition() : NULL_KEY),
true); // assume connection pooling supported by factory
Subject subject = getSubject();
boolean bTxAssociated = false; // the connection is not associated with Tx
HolderDeque deque = null;
try
{
synchronized (this) // reserve one of the created connections
{
if (isTxAssociated(factory)) //if track by Tx check with connections used by current Tx
{
deque = (HolderDeque)m_txMap.get(assoc);
if (deque != null) // connections in-use by TX
{
try
{
connection = factory.matchManagedConnections(deque, subject, cri);
}
catch (NotSupportedException e)
{
assoc.m_bPool = false; // connection pooling not supported
}
if (connection != null) // reuse connection association from previous allocation
{
bTxAssociated = true; // assoc.m_handleSet can be empty if handles closed
assoc = (ConnectionAssoc)m_connectionMap.get(connection);//get full handle set
}
}
}
if (connection == null && assoc.m_bPool) //no connection and pooling possibly supported
{
deque = (HolderDeque)m_poolMap.get(assoc.m_key);
if (deque != null) // unallocated connections available in pool
{
try
{
connection = factory.matchManagedConnections(deque, subject, cri);
}
catch (NotSupportedException e)
{
assoc.m_bPool = false; // connection pooling not supported
}
if (connection != null)
{
deque.remove(connection);
}
}
}
}
if (connection == null)
{
connection = factory.createManagedConnection(subject, cri); // new connection
connection.addConnectionEventListener(this);
}
if (txn != null && !bTxAssociated) // do not re-enlist same connection
{
enlist(connection, txn);
}
try // get handle and if error then retry if this is a stale connection from pool
{
handle = connection.getConnection(subject, cri);
}
catch (ResourceException e)
{
destroyConnection(connection);
if (deque == null || !assoc.m_bPool)
{
throw e; // new connection has error
}
return allocateConnection(factory, cri); // loop/retry
}
synchronized (this)
{
assoc.m_handleSet.add(handle);
m_connectionMap.put(connection, assoc);
if (!bTxAssociated) // If this is the first handle for this connection
{
deque = (HolderDeque)m_txMap.get(assoc); // get the Tx-specific deque
if (deque == null)
{
deque = new HashDeque();
m_txMap.put(assoc, deque);
}
deque.addFirst(connection); // add to deque tracking connections per transaction
}
}
if (s_logger.isDebugEnabled())
{