关于CLOSE BY CLIENT STACK TRACE
程序正常运行,数据库连接可以获取,一些列操作都可以实现,可在debug信息中总会一段时间就报如下错误:
java.lang.Exception : DEBUG — CLOSE BY CLIENT STACK TRACE
at com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:566 )
at com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:234 )
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.destroyResource(C3P0PooledConnectionPool.java:470 )
at com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask.run(BasicResourcePool.java:964 )
at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547 )
跟踪错误代码,发现 是 c3p0 内部的异常输出(红色部分 )
C3p0 相关源码 :
com.mchange.v2.c3p0.impl. NewPooledConnection
public synchronized void close() throws SQLException
{ close( null ); }
private void close( Throwable cause ) throws SQLException
{ close( cause, false ); }
private void close( Throwable cause, boolean forced ) throws SQLException
{
。。。。。。。。。。。。。。。。
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") );
logCloseExceptions ( null , closeExceptions );
if (closeExceptions.size() > 0)
throw new SQLException("Some resources failed to close properly while closing " + this );
}
else
{
this .invalidatingException = cause;
if (Debug.TRACE >= Debug.TRACE_MED )
logCloseExceptions ( cause, closeExceptions );
else
logCloseExceptions ( cause, null );
}
}
}
为何会有这样的错误,一头雾水。
看了下配置文件,觉得可能是automaticTestTable配置引起的,将其注释掉,再运行,发现错误不再出现。
看了下关于 automaticTestTable的作用:
由于Mysql服务器默认的wait_timeout是8小时,也就是说一个connection空闲超过8个小时, Mysql将自动断开该 connection。然而在C3P0 pools中的connections如果空闲超过8小时, Mysql将其断开,而C3P0并不知道该connection已经失效,如果这时有 Client请求connection, C3P0将该失效的Connection提供给Client,将会造成异常。 解决方法可为:1.jdbcUrl上面加一个autoReconnect=true 2.由于autoReconnect=true 在新的connector/J版本里面已经deprecated了,文档里面建议不要使用。 所以配置参数idleConnectionTestPeriod,automaticTestTable
而配置 automaticTestTable却 会报CLOSE BY CLIENT STACK TRACE,故选择配置preferredTestQuery 而不是 automaticTestTable 。
以上只是在使用c3p0是发现的问题,不知道是否理解正确,不过其正真原因到目前还是弄不清楚,望解答!
补充:今天在看到一个见解:(引用主题内容)
我看到那个DEBUG,我说,是调试信息,修改一下LOG4J的等级就行了。
这个群友很不解的问,既然成功了,干嘛还要丢异常出来?
这里就不得不说到两个商业开发的原则问题了。
第一,对上家传入数据严加过滤,对传出给下家的数据仔细检查。
第二,合理使用异常。
忘掉失败,不过要牢记失败中的教训。