com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure, Caused byNo buffer space available (maxim

用Java往mysql中插入数据(大概几千万条,耗时比较长)时出现错误如下:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

Last packet sent to the server was 0 ms ago.

        at sun.reflect.GeneratedConstructorAccessor10.newInstance(Unknown Source)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
        at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1074)
        at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2103)
        at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:718)
        at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:46)
        at sun.reflect.GeneratedConstructorAccessor8.newInstance(Unknown Source)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
        at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:302)
        at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:282)
        at java.sql.DriverManager.getConnection(DriverManager.java:582)
        at java.sql.DriverManager.getConnection(DriverManager.java:185)
        at decompress.DeCompressView.jButton2ActionPerformed(DeCompressView.java:734)
        at decompress.DeCompressView.access$1400(DeCompressView.java:43)
        at decompress.DeCompressView$7.actionPerformed(DeCompressView.java:416)
        at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
        at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
        at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
        at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
        at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
        at java.awt.Component.processMouseEvent(Component.java:6263)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
        at java.awt.Component.processEvent(Component.java:6028)
        at java.awt.Container.processEvent(Container.java:2041)
        at java.awt.Component.dispatchEventImpl(Component.java:4630)
        at java.awt.Container.dispatchEventImpl(Container.java:2099)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4574)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
        at java.awt.Container.dispatchEventImpl(Container.java:2085)
        at java.awt.Window.dispatchEventImpl(Window.java:2478)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Caused by: java.net.SocketException: No buffer space available (maximum connections reached?): connect

从红色部分文字判断,

应该是连接到了最大数的问题。在网上找了很久,有同样症状,但问题多源于超时,他们的解决方法,都没能解决我的问题。

我想我这还是应该从解决链接最大数入手。最终我的代码修改成如下解决了问题:

String url="jdbc:mysql://localhost/weblog";
String user="root";
String password="";
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(url,user,password);
Statement stm = conn.createStatement();

while (Line != null)
{

.......
String insql = "insert into log values (null,'"+IPAddr+"',null,null,null)";
try
{
stm.execute(insql);
}
catch (SQLException e)
{
e.printStackTrace();
}
}//end while
stm.close();
conn.close();
}
而原来出问题原因是我把

Connection conn=DriveManager.getConnection(url,user,password);

Statement stm = conn.createStatement();

写在while循环中,而且没有

stm.close()

conn.close()两句。这样当然会出问题了。

后来在while循环中加了关闭连接的两句,但还是出同样的问题。

后来把生成conn, stm的语句,以及关闭的语句都放在while之外,就解决了。

 

网上同样症状的问题,但是因为超时引起的,解决办法如下地址:

http://blog.csdn.net/leizhendong/archive/2007/04/16/1566484.aspx

http://www.wangzhongyuan.com/archives/610.html

http://www.svn8.com/mysql/200906036013.html

 

<think>嗯,用户遇到了com.mysql.jdbc.exceptions.jdbc4.CommunicationsException的问题,需要解决。首先,我得分析可能的原因。根据提供的引用内容,可能有几个常见原因。比如,网络问题,比如数据库服务器不可达,或者防火墙阻止了端口。然后是MySQL配置问题,比如wait_timeout设置导致连接被关闭,或者版本不兼容,比如JDBC驱动和MySQL版本不一致。还有连接池配置的问题,比如连接没有正确验证或回收。 用户提到程序第二天无法登录,这可能和wait_timeout有关,默认8小时后关闭空闲连接。这时候连接池可能还持有旧的连接,导致异常。所以需要检查连接池的配置,是否有设置自动重连或者验证连接的机制。比如在连接池中配置testOnBorrow或者testWhileIdle,确保连接有效。 另外,版本兼容性也是一个问题。用户如果用的是MySQL 8.0,而JDBC驱动可能还是旧版的,比如5.x,这会导致问题。需要换成8.x的驱动,并且注意URL中的时区设置,比如添加serverTimezone=UTC。 然后,网络问题需要检查数据库的IP、端口是否正确,防火墙是否开放了3306端口。可以用telnet或者ping命令测试连通性。还有MySQL的max_connections参数,是否连接数超过了限制,导致新连接被拒绝。 总结下来,解决方案应该包括检查网络、调整MySQL配置(wait_timeout和interactive_timeout)、更新JDBC驱动、配置连接池参数,以及处理时区问题。同时,异常处理和日志分析也是必要的步骤,帮助定位具体原因。 需要确保用户按照步骤一步步检查,可能还要根据他们的具体情况调整。比如,如果他们使用的是Tomcat连接池,可能需要不同的配置方式。此外,提醒用户查看服务器日志,是否有更详细的错误信息,这有助于更快定位问题。</think>### 分步解决方案:`com.mysql.jdbc.exceptions.jdbc4.CommunicationsException` 连接失败分析与解决 #### **1. 原因分析** - **网络问题**:数据库服务器不可达或端口被防火墙拦截[^3][^5]。 - **MySQL配置超时**:默认`wait_timeout=28800秒`(8小时),超时后MySQL主动关闭空闲连接,但连接池仍持有无效连接引用[^2][^5]。 - **版本不兼容**:JDBC驱动版本与MySQL服务器版本不匹配(如MySQL 8.0需使用`mysql-connector-java-8.x.jar`)[^4]。 - **连接池配置缺陷**:未启用连接有效性检查或自动重连机制。 --- #### **2. 解决方案** ##### **步骤1:检查网络连通性** - 使用`ping <数据库IP>`验证网络可达性。 - 使用`telnet <数据库IP> 3306`(或实际端口)检查端口开放状态。 ##### **步骤2:调整MySQL超时配置** - 修改`my.cnf`文件,增加或修改以下参数: ```ini wait_timeout = 86400 # 空闲连接超时时间(秒) interactive_timeout = 86400 max_connections = 200 # 避免连接数耗尽 ``` - 重启MySQL服务后生效[^5]。 ##### **步骤3:更新JDBC驱动与URL** - **驱动版本**:MySQL 8.0需使用`mysql-connector-java-8.0.x.jar`,替换旧版本驱动[^4]。 - **连接URL**:添加时区与SSL配置: ```java jdbc:mysql://localhost:3306/dbname?serverTimezone=UTC&autoReconnect=true&useSSL=false ``` ##### **步骤4:配置连接池参数** 以**HikariCP**为例,添加连接有效性检查与重试机制: ```java HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:mysql://localhost/dbname"); config.setConnectionTestQuery("SELECT 1"); // 验证连接的SQL config.setConnectionTimeout(30000); // 连接获取超时时间(毫秒) config.setIdleTimeout(600000); // 空闲连接超时时间(毫秒) config.setMaxLifetime(1800000); // 连接最大存活时间(毫秒) ``` ##### **步骤5:处理时区与SSL兼容性** - 若报时区错误,在URL中添加`serverTimezone=UTC`。 - 若SSL未启用,添加`useSSL=false`[^4]。 --- #### **3. 验证与异常处理** - **日志分析**:检查MySQL错误日志(默认路径`/var/log/mysql/error.log`)和应用日志,定位具体错误[^3]。 - **代码层重试机制**: ```java try { Connection conn = dataSource.getConnection(); // 执行SQL } catch (CommunicationsException e) { // 触发连接池重建或重试逻辑 } ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值