// methods below must be called from sync'ed methods
/*
* If a throwable cause is provided, the PooledConnection is known to be broken (cause is an invalidating exception)
* and this method will not throw any exceptions, even if some resource closes fail.
*
* If cause is null, then we think the PooledConnection is healthy, and we will report (throw) an exception
* if resources unexpectedlay fail to close.
*/
private void close( Throwable cause ) throws SQLException
{ close( cause, false ); }
private void close( Throwable cause, boolean forced ) throws SQLException
{
assert Thread.holdsLock( this );
if ( this.invalidatingException == null )
{
List closeExceptions = new LinkedList();
// cleanup ResultSets
cleanupResultSets( closeExceptions );
// cleanup uncached Statements
// System.err.println(this + ".close( ... ) -- uncachedActiveStatements: " + uncachedActiveStatements);
cleanupUncachedStatements( closeExceptions );
// cleanup cached Statements
try
{ closeAllCachedStatements(); }
catch ( SQLException e )
{ closeExceptions.add(e); }
if ( forced )
{
// reset transaction state
try { C3P0ImplUtils.resetTxnState( physicalConnection, forceIgnoreUnresolvedTransactions, autoCommitOnClose, false ); }
catch (Exception e)
{
if (logger.isLoggable( MLevel.FINER ))
logger.log( MLevel.FINER,
"Failed to reset the transaction state of " + physicalConnection + "just prior to close(). " +
"Only relevant at all if this was a Connection being forced close()ed midtransaction.",
e );
}
}
// cleanup physicalConnection
try
{ physicalConnection.close(); }
catch ( SQLException e )
{
if (logger.isLoggable( MLevel.FINER ))
logger.log( MLevel.FINER, "Failed to close physical Connection: " + physicalConnection, e );
closeExceptions.add(e);
}
// update our state to bad status and closed, and log any exceptions
if ( connection_status == ConnectionTester.CONNECTION_IS_OKAY )
connection_status = ConnectionTester.CONNECTION_IS_INVALID;
if ( cause == null )
{
this.invalidatingException = NORMAL_CLOSE_PLACEHOLDER;
if ( Debug.DEBUG && logger.isLoggable( MLevel.FINEST ) )
logger.log( MLevel.FINEST, this + " closed by a client.", new Exception("DEBUG -- CLOSE BY CLIENT STACK TRACE") );//num:646 in the NewPooledConnection.java
/*
Note that:
1、This is not an exception, the new Exception is used merely to show execution path for debug purposes.
2、And yes, this is only a debug message (actually, FINEST is the lowest possible level in java.util.logging).
To wrap this up: ignore and tune your logging levels to skip these.
既然成功了,干嘛还要丢异常出来?
这里就不得不说到两个商业开发的原则问题了。第一,对上家传入数据严加过滤,对传出给下家的数据仔细检查。
第二,合理使用异常。
第一点其实很简单的。也就是模块化开发的一个思想问题。对自己的行为负责。前端返回的数据究竟是什么,需要进行校验。不合格的剔除或者是修正。合格的处理完后,在传出之前也要加以校验,是否合格
结合到 “合理使用异常” 这句话来说呢,就是说,需要抛出异常的时候,就抛出。不需要抛出的时候,就不抛出。对程序员来说,在必要的时候看到一串异常信息,是最合适的事情了。
*/