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