关于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是发现的问题,不知道是否理解正确,不过其正真原因到目前还是弄不清楚,望解答!

补充:今天在http://hi.baidu.com/xhr8334/blog/item/cf15d1a6deb235fc9052ee9b.html看到一个见解:(引用主题内容)

我看到那个DEBUG,我说,是调试信息,修改一下LOG4J的等级就行了。

这个群友很不解的问,既然成功了,干嘛还要丢异常出来?

这里就不得不说到两个商业开发的原则问题了。

第一,对上家传入数据严加过滤,对传出给下家的数据仔细检查。

第二,合理使用异常。

第一点其实很简单的。也就是模块化开发的一个思想问题。对自己的行为负责。前端返回的数据究竟是什么,需要进行校验。不合格的剔除或者是修正。合格的处理完后,在传出之前也要加以校验,是否合格。

具体到这个问题里,就是来自Spring关于数据源的那个配置文件。

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">

//略去数据源相关信息的配置

</bean>

这个配置文件里,有两个信息是很管用的。一个是class,一个是destroy-method。简单点说,一个是数据源的实现类,一个是析构方法。Spring在读取这个配置文件以后,需要根据这些信息来实例化一些类,然后内部再根据中间的那些配置信息来实际构造数据源。比如username啥的。

可是来了个问题。不能保证这里的ComboPooledDataSource数据源一定是可用的,也不能保证close方法一定能关闭连接,对吧?Spring本身不能检查这个类是否真实有效,毫无Bug。实际上呢,也检查不了。同样的,close方法是否有效,也需要进行检查。这就是我刚才说的,对上家数据的严加检查。

那好吧,怎么检查呢?最简洁的方法莫过于实际构造一下,连接池,获取数据库连接,执行一个测试语句,然后关闭连接。如果一切都成功,那就OK。关于那个测试语句,配置过WebSphere数据源的同学们还记得不?有个SQL语句会默认的写在数据源配置里,是 " SELECT 1 FROM TABLE "。嗯,对的,这个就是测试语句。

这一套流程能走得通,走的顺,那么就可以在自己能力范围内说这个数据源和连接池是能用的,对吧?

这里补充一个知识。java.sql.Connection,这玩意不是class,是interface。

声明是:public interface
Connection
extends Wrapper 。

任何一个JDBC数据库连接的实现类都应该实现这个接口的全部方法。比如,close。API里的描述是,立即释放此
Connection 对象的数据库和 JDBC 资源,而不是等待它们被自动释放。

熟悉Java的同学们应该记得一点,在规范里有个要求,就是接口的实现类必须实现接口的所有方法。但是呢,这句话还有个意思,那就是,你可以在实现所有方法之外,再写几个方法。没人会管你。

啊哈,那就有疑问了。虽然API规定了close是关闭连接释放资源的。但这只是你接口的一厢情愿。也许人家实现厂家觉得close方法不够帅,要改成closeConnection。那。。。Spring总不好傻傻的去死扣close方法来关闭连接吧?虽然这方法必须实现,但是可没说一定要有内容啊。如果是空方法呢?

所以有了destroy-method这个配置项的出现。Spring说,不碍的,您老人家看哪个爽,告诉我就行。

现在测试完了。一切都成功了。

现在来看看第二个问题。合理使用异常。

又遇到一个问题。既然测试成功了,那总得给用户一点交待吧?难道说,测试成功了,就闷声大发财了?显然不合适嘛。可以试想一下,你是程序员,然后点了个按钮,测试。结果呢,实际上是测试成功了,但是系统啥动静都不给你。然后你傻傻的等痴痴的盼,一直等到天荒地老……嗯嗯,扯的有点远。如果你等一个小时还不见动静,活不见人死不见尸的,你说你会不会骂娘?

那么怎么通知才能保证一定有效呢?println?这个不见得一定能看到。因为别人也可能在同时输出信息,一下就刷掉了。那么有同学说了,最好是能暂停一下,我输出以后,就暂停了,不动了。

嗯,很好。

大家想想看,输出一大堆东西,然后此程序不动了,不继续执行了,这是啥玩意?

这不就是异常嘛!

只有异常能保证程序员一定能看到这个信息,比如,测试成功。这就是为什么Spring要采用这种方式来通知的原因。

这里呢,我想更正同学们一个习惯成自然的想法。异常不一定是通知坏消息的。异常就是异常,只要你愿意,你甚至可以在代码执行成功的时候,throws一个Exception。异常只不过是比较激烈的一种通知方式而已。无他,仅此而已。

现在又有个问题来了。既然要测试,而且每次执行到此处的时候都要测试一下。那么……难道都卡在这里不走了啊?显然更不合适啊。

熟悉log4J的同学应该看出来了,这是log4J输出的日志。很明显的,这种日志只应当在开发期间存在,不应该在发布期间存在。因为开发期间数据库变动很大,比如改表啊,改数据库配置啊。所以需要通知用户是否成功。但是产品一旦开发完毕,正式发布,这种信息就不应再出现,因为商业化运作的应用不允许乱动配置的,对不?

所以log4J提供了一种方法。消息级别。INFO的时候,是看不到这个异常的。实现起来也很好办,catch了,然后不做任何处理,也就是空的catch块。

具体实现的时候可以在catch里判断一下,如果等级是INFO的话,就不做任何事。如果不是,那就按照规则去做。

结合到 “合理使用异常” 这句话来说呢,就是说,需要抛出异常的时候,就抛出。不需要抛出的时候,就不抛出。对程序员来说,在必要的时候看到一串异常信息,是最合适的事情了。

关于异常的使用,这里不展开说了。有兴趣的同学可以参见林锐博士的 高质量Java编程。

关于CLOSE BY CLIENT STACK TRACE的更多相关文章

  1. java.lang.Exception: DEBUG -- CLOSE BY CLIENT STACK TRACE 的理解

    [2013-12-06 11:06:21,715] [C3P0PooledConnectionPoolManager[identityToken->2tl0n98y1iwg7cbdzzq7a|7 ...

  2. DEBUG -- CLOSE BY CLIENT STACK TRACE问题的两种解决方案,整理自网络

    1.DEBUG -- CLOSE BY CLIENT STACK TRACE 最近用c3p0遇到各种奇怪的问题,也不知道是它不行还是我不行. 今天又遇到了一个"DEBUG -- CLOSE ...

  3. XDebug 自动开启PHP Stack Trace, 导致PHP Log 超1G

    昨天早上突然发现测试服务器空间满了,用du挨个文件夹查看,发现是php debug log占地极大,有的log直接有1G,打开后发现极其多的php stack trace. 立刻到主服务器查看,主服务 ...

  4. dump 分析模式之 INCORRECT STACK TRACE - djm2005dy的专栏 - 博客频道 - CSDN.NET

    Dump 分析模式之 INCORRECT STACK TRACE dump 分析模式之 INCORRECT STACK TRACE 翻译自 MDA-Anthology Page288  初学者常犯的错 ...

  5. Rethrowing exceptions and preserving the full call stack trace

    refer:http://weblogs.asp.net/fmarguerie/archive/2008/01/02/rethrowing-exceptions-and-preserving-the- ...

  6. Eclipse下Android开发错误之Unable to execute dex: java.nio.BufferOverflowException. Check the Eclipse log for stack trace

    升级了Android版本后,在运行应用时提示: [2013-11-27 10:37:35 - Dex Loader] Unable to execute dex: java.nio.BufferOve ...

  7. Android -- java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available

    使用Bundle 的getParcelableArray 出现了以下错误: Class not found when unmarshallingjava.lang.ClassNotFoundExcep ...

  8. 让Xcode的 stack trace信息可读

    让Xcode的 stack trace信息可读 昨天在写 iOS 代码的时候,调试的时候模拟器崩溃了.异常停在了如下整个 main 函数的入口处: int main(int argc, char *a ...

  9. 项目跑起来之后,一会儿后台就会报错Illegal access: this web application instance has been stopped already. Could not load [com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask]. The following stack trace

    一月 24, 2016 6:42:54 下午 org.apache.catalina.loader.WebappClassLoaderBase checkStateForResourceLoading ...

随机推荐

  1. python 拆解包

    Python 拆解包 转自:https://www.jianshu.com/p/22c538a58bcc python中的解包可以这样理解:一个list是一个整体,想把list中每个元素当成一个个个体 ...

  2. 023.Python的随机模块和时间模块

    一 random 随机模块 1.1 获取随机0-1之间的小数(左闭右开)  0<= x < 1 import random res = random.random() print(res) ...

  3. Vue2--非父子组件通信笔记

    核心要点: var Event=new Vue(); Event.$emit(事件名称, 数据) Event.$on(事件名称,function(data){ //data }.bind(this)) ...

  4. Pytorch——BERT 预训练模型及文本分类

    BERT 预训练模型及文本分类 介绍 如果你关注自然语言处理技术的发展,那你一定听说过 BERT,它的诞生对自然语言处理领域具有着里程碑式的意义.本次试验将介绍 BERT 的模型结构,以及将其应用于文 ...

  5. 吴裕雄--天生自然 PYTHON3开发学习:MongoDB

    import pymongo myclient = pymongo.MongoClient("mongodb://localhost:27017/") mydb = myclien ...

  6. Django中间件-跨站请求伪造-django请求生命周期-Auth模块-seettings实现可插拔配置(设计思想)

    Django中间件 一.什么是中间件 django中间件就是类似于django的保安;请求来的时候需要先经过中间件,才能到达django后端(url,views,models,templates), ...

  7. 函数动态传参,命名空间,gloabal,nonlocal关键字

    一.函数参数->动态传参(形参的第三种) 动态参数分为两种: 1)动态接收位置参数 普通的位置传参: def func(quality_food,junk_food): print('我要吃', ...

  8. 【线段树】Interval GCD

    题目描述 给定一个长度为N的数列A,以及M条指令 (N≤5*10^5, M<=10^5),每条指令可能是以下两种之一: "C l r d",表示把 A[l],A[l+1],- ...

  9. 使用idea创建spring mvc项目图文教程

    使用idea创建spring mvc项目图文教程 前言: 使用惯了eclipse的朋友,如果刚换成了idea或许有些不习惯.但是使用idea之后,就会love上idea了.本文将通过图文讲解怎么通过i ...

  10. Box and Ball

    题目描述 We have N boxes, numbered 1 through N. At first, box 1 contains one red ball, and each of the o ...