com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception: (转载:http://www.javaeye.com/topic/38506)

com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception:

** BEGIN NESTED EXCEPTION **

java.io.EOFException

STACKTRACE:

java.io.EOFException
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1905)
at com.mysql.jdbc.MysqlIO.readPacket(MysqlIO.java:483)
at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:965)
at com.mysql.jdbc.Connection.createNewIO(Connection.java:2558)
at com.mysql.jdbc.Connection.<init>(Connection.java:1485)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:266)
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at littleworld.YoukuVideoInfoParse.dbExecute(YoukuVideoInfoParse.java:375)
at littleworld.YoukuVideoInfoParse.parseSingle(YoukuVideoInfoParse.java:336)
at littleworld.YoukuVideoInfoParse.parse(YoukuVideoInfoParse.java:46)
at littleworld.YoukuVideoInfoParse.main(YoukuVideoInfoParse.java:31)


** END NESTED EXCEPTION **

查看了Mysql的文档,以及Connector/J的文档以及在线说明发现,出现这种异常的原因是:

Mysql服务器默认的“wait_timeout”是8小时,也就是说一个connection空闲超过8个小时,Mysql将自动断开该connection。这就是问题的所在,在C3P0 pools中的connections如果空闲超过8小时,Mysql将其断开,而C3P0并不知道该connection已经失效,如果这时有Client请求connection,C3P0将该失效的Connection提供给Client,将会造成上面的异常。

解决的方法有3种:

1.增加wait_timeout的时间。
2.减少Connection pools中connection的lifetime。
3.测试Connection pools中connection的有效性。

解决思路:2
mysql配置中的wait_timeout值一定要大于等于连接池种的idel_timeout值。
否则mysql会在wait_timeout的时间后关闭连接,
然而连接池还认为该连接可用,
这样就会产生SocketException。
http://univerz.bokee.com/2410360.html

http://andyao.javaeye.com/blog/38506

1.//set to 'SELECT 1'
2.validationQuery = "SELECT 1"
3.//set to 'true'
4.testWhileIdle = "true"
5.//some positive integer
6.timeBetweenEvictionRunsMillis = 3600000
7.//set to something smaller than 'wait_timeout'
8.minEvictableIdleTimeMillis = 18000000
9.//if you don't mind a hit for every getConnection(), set to "true"
10.testOnBorrow = "true"
C3P0增加以下配置信息:

1.//获取connnection时测试是否有效

1.testConnectionOnCheckin = true
2.//自动测试的table名称

3.automaticTestTable=C3P0TestTable

4.//set to something much less than wait_timeout, prevents connections from going stale
5.idleConnectionTestPeriod = 18000
6.//set to something slightly less than wait_timeout, preventing 'stale' connections from being handed out
7.maxIdleTime = 25000
8.//if you can take the performance 'hit', set to "true"
9.testConnectionOnCheckout = true

 

解决方式:编辑/etc/my.cnf(windows下为my.ini),将超时时间设置为10年,在[mysqld]后面加入:
wait_timeout=315360000

 

注意参数:

//如果设为true那么在取得连接的同时将校验连接的有效性。Default: false
testConnectionOnCheckin = true
//自动测试的table名称,c3p0将建一张名为C3P0TestTable的空表,并使用其自带的查询语句进行测试。如果定义了这个参数那么
//属性preferredTestQuery将被忽略。你不能在这张Test表上进行任何操作,它将只供c3p0测试使用。Default: null
automaticTestTable=C3P0TestTable
//每1800秒检查所有连接池中的空闲连接。Default: 0
idleConnectionTestPeriod = 1800
//最大空闲时间,3600秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0
maxIdleTime = 3600
/**因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的
时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable
等方法来提升连接测试的性能。Default: false */
testConnectionOnCheckout = true

网上有很多种解决方案.
1. 修改mysql参数,在mysql.ini的mysqld下面添加
wait_timeout=5
interactive_timeout=5
重启mysql
2.写调试程序
故意使一个连接空闲6秒,立马报错
3.修改c3p0配置,设置maxIdleTime的值,
只有这个值小于mysql的wait_timeout就行了,
调试 ok
4 .还原所有配置,在项目中增加maxIdleTime配置

http://www.javaeye.com/topic/38506

posted @ 2012-11-01 10:32  andysd  阅读(1050)  评论(0编辑  收藏  举报