• 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

  • 相关阅读:
    开发脚本自动部署及监控
    内存进程与软件包安装
    Linux常用指令
    网络协议
    Python基础(二)
    python基础(一)
    shell编程
    正则与sed,grep,awk三剑客
    网络配置和元字符
    nginx
  • 原文地址:https://www.cnblogs.com/andysd/p/2749323.html
Copyright © 2020-2023  润新知