this.sharedTaskRunner = taskRunner;
class PooledConnectionResourcePoolManager implements ResourcePool.Manager
{
SynchronizedIntHolder totalOpenedCounter = new SynchronizedIntHolder();
SynchronizedIntHolder connectionCounter = new SynchronizedIntHolder();
SynchronizedIntHolder failedCloseCounter = new SynchronizedIntHolder();
public Object acquireResource() throws Exception
{
PooledConnection out = (auth.equals( C3P0ImplUtils.NULL_AUTH ) ?
cpds.getPooledConnection() :
cpds.getPooledConnection( auth.getUser(),
auth.getPassword() ) );
connectionCounter.increment();
totalOpenedCounter.increment();
try
{
if (scache != null)
{
if (out instanceof C3P0PooledConnection)
((C3P0PooledConnection) out).initStatementCache(scache);
else if (out instanceof NewPooledConnection)
((NewPooledConnection) 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.");
}
}
out.addConnectionEventListener( cl );
return out;
}
catch (Exception e)
{
if (logger.isLoggable( MLevel.WARNING ))
logger.warning("A PooledConnection was acquired, but an Exception occurred while preparing it for use. " +
"Attempting to destroy.");
try { destroyResource( out ); }
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 ( testConnectionOnCheckout )
{
if ( logger.isLoggable( MLevel.FINER ) )
finerLoggingTestPooledConnection( resc, "CHECKOUT" );
else
testPooledConnection( resc );
}
}
public void refurbishResourceOnCheckin( Object resc ) throws Exception
{
if ( testConnectionOnCheckin )
{
if ( logger.isLoggable( MLevel.FINER ) )
finerLoggingTestPooledConnection( resc, "CHECKIN" );
else
testPooledConnection( resc );
}
}
public void refurbishIdleResource( Object resc ) throws Exception
{
if ( logger.isLoggable( MLevel.FINER ) )
finerLoggingTestPooledConnection( resc, "IDLE CHECK" );
else
testPooledConnection( resc );
}
private void finerLoggingTestPooledConnection(Object resc, String testImpetus) throws Exception
{
logger.finer("Testing PooledConnection [" + resc + "] on " + testImpetus + ".");
try
{
testPooledConnection( resc );
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
{
PooledConnection pc = (PooledConnection) resc;
int status;
Connection conn = null;
Throwable rootCause = null;
try
{
//we don't want any callbacks while we're testing the resource
pc.removeConnectionEventListener( cl );
conn = pc.getConnection(); //checkout proxy connection
if ( testQuery == null )
status = connectionTester.activeCheckConnection( conn );
else
{
if (connectionTester instanceof QueryConnectionTester)
status = ((QueryConnectionTester) connectionTester).activeCheckConnection( conn, testQuery );
else
{
// System.err.println("[c3p0] WARNING: testQuery '" + testQuery +
// "' ignored. Please set a ConnectionTester that implements " +
// "com.mchange.v2.c3p0.advanced.QueryConnectionTester, or use the " +
// "DefaultConnectionTester, to test with the testQuery.");
logger.warning("[c3p0] testQuery '" + testQuery +
"' ignored. Please set a ConnectionTester that implements " +
"com.mchange.v2.c3p0.advanced.QueryConnectionTester, or use the " +
"DefaultConnectionTester, to test with the testQuery.");
status = connectionTester.activeCheckConnection( conn );
}
}
}
catch (SQLException e)
{
if (Debug.DEBUG)
logger.log(MLevel.FINE, "A Connection test failed with an Exception.", e);
//e.printStackTrace();
status = ConnectionTester.CONNECTION_IS_INVALID;
// System.err.println("rootCause ------>");
// e.printStackTrace();
rootCause = e;
}
finally
{
ConnectionUtils.attemptClose( conn ); //invalidate proxy connection
pc.addConnectionEventListener( cl ); //should we move this to CONNECTION_IS_OKAY case? (it should work either way)
}
switch (status)
{
case ConnectionTester.CONNECTION_IS_OKAY:
break; //no problem, babe
case ConnectionTester.DATABASE_IS_INVALID:
rp.resetPool();
//intentional cascade...
case ConnectionTester.CONNECTION_IS_INVALID:
Exception throwMe;
if (rootCause == null)
throwMe = new SQLException("Connection is invalid");
else
throwMe = SqlUtils.toSQLException("Connection is invalid", rootCause);
throw throwMe;
default:
throw new Error("Bad Connection Tester (" +
connectionTester + ") " +
"returned invalid status (" + status + ").");
}
}
public void destroyResource(Object resc) throws Exception
{
try
{
if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable( MLevel.FINER ))
logger.log( MLevel.FINER, "Preparing to destroy PooledConnection: " + resc);
((PooledConnection) resc).close();
connectionCounter.decrement();
if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable( MLevel.FINER ))
logger.log( MLevel.FINER,
"Successfully destroyed PooledConnection: " + resc +
". Currently open Connections: " + connectionCounter.getValue() +
"; Failed close count: " + failedCloseCounter.getValue() +
"; Total processed by this pool: " + totalOpenedCounter.getValue());
}
catch (Exception e)
{
failedCloseCounter.increment();
if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable( MLevel.FINER ))
logger.log( MLevel.FINER, "Failed to destroy PooledConnection: " + resc +
". Currently open Connections: " + connectionCounter.getValue() +
"; Failed close count: " + failedCloseCounter.getValue() +
"; Total processed by this pool: " + totalOpenedCounter.getValue());
throw e;
}
}