mysql 异常com.mysql.jdbc.CommunicationsException
### MySQL异常com.mysql.jdbc.CommunicationsException解析及解决方案 #### 异常概述 在Java应用程序中使用MySQL数据库时,可能会遇到`com.mysql.jdbc.CommunicationsException`这一异常。该异常通常意味着与MySQL服务器的通信出现问题,例如网络中断、服务器端主动断开连接等。 #### 异常详情 本次异常的具体描述为:“Communications link failure due to underlying exception: **BEGINNESTED EXCEPTION** java.io.EOFException STACK TRACE: 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) ...” 这段描述中提到了EOFException(End Of File Exception),即文件结束异常,这通常发生在应用程序试图从流中读取数据但没有更多数据可读的情况下。具体到本例中,是在尝试与MySQL服务器建立连接时遇到了这个问题。 #### 原因分析 异常发生的原因在于MySQL服务器默认设置了一个超时时间(`wait_timeout`),如果一个连接长时间未被使用,则MySQL会自动断开这个连接。在这个案例中,C3P0连接池中的某些连接由于长时间空闲而被MySQL服务器断开,但是C3P0连接池并不知道这些连接已经失效,当客户端再次请求这些连接时,就产生了`CommunicationsException`异常。 #### 解决方案 根据异常描述,解决此问题有三种基本方法: 1. **增加`wait_timeout`时间**:通过修改MySQL服务器的配置文件,增加`wait_timeout`的值,使连接保持更长的时间不被断开。这种方式简单直接,但如果应用本身对连接使用频率不高,可能会导致不必要的资源占用。 2. **减少连接池中连接的生命周期**:调整C3P0连接池的配置参数,降低连接的最大空闲时间或生命周期。这种方式可以避免无效连接的积累,减少异常的发生几率,同时也能够提高资源利用效率。 3. **测试连接池中连接的有效性**:启用连接池的连接有效性检查机制,确保从连接池中获取的每个连接都是有效的。这可以通过设置相应的参数来实现。 #### 具体配置建议 针对第二种解决方案,具体可以采用以下配置: 1. **testWhileIdle**:"true",表示在连接空闲时进行有效性检测。 2. **timeBetweenEvictionRunsMillis**:指定检测连接有效性的时间间隔,单位毫秒。 3. **minEvictableIdleTimeMillis**:设置连接被废弃前的最小空闲时间,单位毫秒。 4. **testOnBorrow**:"true",表示在获取连接时进行有效性检测。 对于C3P0连接池,还可以添加以下配置: 1. **testConnectionOnCheckin**:设置为"true",表示在归还连接时进行有效性检测。 2. **automaticTestTable**:设置用于测试连接有效性的表名。 3. **timeBetweenConnectErrorMillis**:设置两次连接错误之间的间隔时间,以防止频繁尝试连接。 #### 结论 `com.mysql.jdbc.CommunicationsException`通常是由于MySQL服务器超时断开空闲连接所引起。通过适当调整MySQL服务器的`wait_timeout`配置或C3P0连接池的相关参数,可以有效地解决此类问题。在实际操作过程中,还需要根据具体的业务场景选择合适的配置方案,以达到最佳的效果。
** 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种:
- 粉丝: 0
- 资源: 16
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
- 1
- 2
前往页