final boolean connectionTesterIsDefault = (connectionTester instanceof DefaultConnectionTester);
public Object acquireResource() throws Exception
{
PooledConnection out;
if ( connectionCustomizer == null)
{
out = (auth.equals( C3P0ImplUtils.NULL_AUTH ) ?
cpds.getPooledConnection() :
cpds.getPooledConnection( auth.getUser(),
auth.getPassword() ) );
}
else
{
try
{
WrapperConnectionPoolDataSourceBase wcpds = (WrapperConnectionPoolDataSourceBase) cpds;
out = (auth.equals( C3P0ImplUtils.NULL_AUTH ) ?
wcpds.getPooledConnection( connectionCustomizer, parentDataSourceIdentityToken ) :
wcpds.getPooledConnection( auth.getUser(),
auth.getPassword(),
connectionCustomizer, parentDataSourceIdentityToken ) );
}
catch (ClassCastException e)
{
throw SqlUtils.toSQLException("Cannot use a ConnectionCustomizer with a non-c3p0 ConnectionPoolDataSource." +
" ConnectionPoolDataSource: " + cpds.getClass().getName(), e);
}
}
//connectionCounter.increment();
//totalOpenedCounter.increment();
try
{
if (scache != null)
{
if (c3p0PooledConnections)
((AbstractC3P0PooledConnection) out).initStatementCache(scache);
else
{
// System.err.print("Warning! StatementPooling not ");
// System.err.print("implemented for external (non-c3p0) ");
// System.err.println("ConnectionPoolDataSources.");
logger.warning("StatementPooling not " +
"implemented for external (non-c3p0) " +
"ConnectionPoolDataSources.");
}
}
// log and clear any SQLWarnings present upon acquisition
Connection con = null;
try
{
waitMarkPooledConnectionInUse(out);
con = out.getConnection();
SQLWarnings.logAndClearWarnings( con );
}
finally
{
//invalidate the proxy Connection
ConnectionUtils.attemptClose( con );
unmarkPooledConnectionInUse(out);
}
return out;
}
catch (Exception e)
{
if (logger.isLoggable( MLevel.WARNING ))
logger.log(MLevel.WARNING,
"A PooledConnection was acquired, but an Exception occurred while preparing it for use. Attempting to destroy.",
e);
try { destroyResource( out, false ); }
catch (Exception e2)
{
if (logger.isLoggable( MLevel.WARNING ))
logger.log( MLevel.WARNING,
"An Exception occurred while trying to close partially acquired PooledConnection.",
e2 );
}
throw e;
}
finally
{
if (logger.isLoggable( MLevel.FINEST ))
logger.finest(this + ".acquireResource() returning. " );
//"Currently open Connections: " + connectionCounter.getValue() +
//"; Failed close count: " + failedCloseCounter.getValue() +
//"; Total processed by this pool: " + totalOpenedCounter.getValue());
}
}
// REFURBISHMENT:
// the PooledConnection refurbishes itself when
// its Connection view is closed, prior to being
// checked back in to the pool. But we still may want to
// test to make sure it is still good.
public void refurbishResourceOnCheckout( Object resc ) throws Exception
{
if ( connectionCustomizer != null )
{
Connection physicalConnection = null;
try
{
physicalConnection = ((AbstractC3P0PooledConnection) resc).getPhysicalConnection();
waitMarkPhysicalConnectionInUse( physicalConnection );
if ( testConnectionOnCheckout )
{
if ( Debug.DEBUG && logger.isLoggable( MLevel.FINER ) )
finerLoggingTestPooledConnection( resc, "CHECKOUT" );
else
testPooledConnection( resc );
}
connectionCustomizer.onCheckOut( physicalConnection, parentDataSourceIdentityToken );
}
catch (ClassCastException e)
{
throw SqlUtils.toSQLException("Cannot use a ConnectionCustomizer with a non-c3p0 PooledConnection." +
" PooledConnection: " + resc +
"; ConnectionPoolDataSource: " + cpds.getClass().getName(), e);
}
finally
{ unmarkPhysicalConnectionInUse(physicalConnection); }
}
else
{
if ( testConnectionOnCheckout )
{
PooledConnection pc = (PooledConnection) resc;
try
{
waitMarkPooledConnectionInUse( pc );
assert !Boolean.FALSE.equals(pooledConnectionInUse( pc )); //null or true are okay
if ( Debug.DEBUG && logger.isLoggable( MLevel.FINER ) )
finerLoggingTestPooledConnection( pc, "CHECKOUT" );
else
testPooledConnection( pc );
}
finally
{
unmarkPooledConnectionInUse(pc);
}
}
}
}
// TODO: refactor this by putting the connectionCustomizer if logic inside the (currently repeated) logic
public void refurbishResourceOnCheckin( Object resc ) throws Exception
{
if ( connectionCustomizer != null )
{
Connection physicalConnection = null;
try
{
physicalConnection = ((AbstractC3P0PooledConnection) resc).getPhysicalConnection();
// so by the time we are checked in, all marked-for-destruction statements should be closed.
waitMarkPhysicalConnectionInUse( physicalConnection );
connectionCustomizer.onCheckIn( physicalConnection, parentDataSourceIdentityToken );
SQLWarnings.logAndClearWarnings( physicalConnection );
if ( testConnectionOnCheckin )
{
if ( Debug.DEBUG && logger.isLoggable( MLevel.FINER ) )
finerLoggingTestPooledConnection( resc, "CHECKIN" );
else
testPooledConnection( resc );
}
}
catch (ClassCastException e)
{
throw SqlUtils.toSQLException("Cannot use a ConnectionCustomizer with a non-c3p0 PooledConnection." +
" PooledConnection: " + resc +
"; ConnectionPoolDataSource: " + cpds.getClass().getName(), e);
}
finally
{ unmarkPhysicalConnectionInUse(physicalConnection); }
}
else
{
PooledConnection pc = (PooledConnection) resc;
Connection con = null;
try
{
// so by the time we are checked in, all marked-for-destruction statements should be closed.
waitMarkPooledConnectionInUse( pc );
con = pc.getConnection();
SQLWarnings.logAndClearWarnings(con);
if ( testConnectionOnCheckin )
{
if ( Debug.DEBUG && logger.isLoggable( MLevel.FINER ) )
finerLoggingTestPooledConnection( resc, con, "CHECKIN" );
else
testPooledConnection( resc, con );
}
}
finally
{
// close the proxy Connection
ConnectionUtils.attemptClose(con);
unmarkPooledConnectionInUse( pc );
}
}
}
public void refurbishIdleResource( Object resc ) throws Exception
{
PooledConnection pc = (PooledConnection) resc;
if ( Debug.DEBUG && logger.isLoggable( MLevel.FINER ) )
finerLoggingTestPooledConnection( resc, "IDLE CHECK" );
else
testPooledConnection( resc );
}
private void finerLoggingTestPooledConnection(Object resc, String testImpetus) throws Exception
{ finerLoggingTestPooledConnection( resc, null, testImpetus); }
private void finerLoggingTestPooledConnection(Object resc, Connection proxyConn, String testImpetus) throws Exception
{
logger.finer("Testing PooledConnection [" + resc + "] on " + testImpetus + ".");
try
{
testPooledConnection( resc, proxyConn );
logger.finer("Test of PooledConnection [" + resc + "] on " + testImpetus + " has SUCCEEDED.");
}
catch (Exception e)
{
logger.log(MLevel.FINER, "Test of PooledConnection [" + resc + "] on "+testImpetus+" has FAILED.", e);
e.fillInStackTrace();
throw e;
}
}
private void testPooledConnection(Object resc) throws Exception
{ testPooledConnection( resc, null ); }
private void testPooledConnection(Object resc, Connection proxyConn) throws Exception
{
PooledConnection pc = (PooledConnection) resc;
assert !Boolean.FALSE.equals(pooledConnectionInUse( pc )); //null or true are okay
Throwable[] throwableHolder = EMPTY_THROWABLE_HOLDER;
int status;
Connection openedConn = null;
Throwable rootCause = null;
try
{
// No! Connection must be maked in use PRIOR TO Connection test
//waitMarkPooledConnectionInUse( pc );
// if this is a c3p0 pooled-connection, let's get underneath the
// proxy wrapper, and test the physical connection sometimes.
// this is faster, when the testQuery would not otherwise be cached,
// and it avoids a potential statusOnException() double-check by the
// PooledConnection implementation should the test query provoke an
// Exception
Connection testConn;
if (scache != null) //when there is a statement cache...
{
// if it's the slow, default query, faster to test the raw Connection
if (testQuery == null && connectionTesterIsDefault && c3p0PooledConnections)
testConn = ((AbstractC3P0PooledConnection) pc).getPhysicalConnection();
else //test will likely be faster on the proxied Connection, because the test query is probably cached
testConn = (proxyConn == null ? (openedConn = pc.getConnection()) : proxyConn);
}
else //where there's no statement cache, better to use the physical connection, if we can get it
{
if (c3p0PooledConnections)
testConn = ((AbstractC3P0PooledConnection) pc).getPhysicalConnection();
else
testConn = (proxyConn == null ? (openedConn = pc.getConnection()) : proxyConn);
}
if ( testQuery == null )
status = connectionTester.activeCheckConnection( testConn );
else