2015-07-13 68 views
0
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure 

遇到此错误,如果有人可以使用我提供的代码来修复它的答案,那就太好了。我不擅长SQL,我只是在帮助一位朋友。SQL/JAVA通信链接错误偶尔会发生JDBC

下面是代码:

public static Connection con = null; 
public static Statement stmt; 
public static boolean connectionMade; 
public static void createConnection() { 
    try { 
     Class.forName("com.mysql.jdbc.Driver").newInstance(); 
     con = DriverManager.getConnection("jdbc:mysql://localhost/highscores","root","root"); 
     stmt = con.createStatement(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 
public static ResultSet query(String s) throws SQLException { 
    try { 
     if (s.toLowerCase().startsWith("select")) { 
      ResultSet rs = stmt.executeQuery(s); 
      return rs; 
     } else { 
      stmt.executeUpdate(s); 
     } 
     return null; 
    } catch (Exception e) { 
     destroyConnection(); 
     createConnection(); 
     e.printStackTrace(); 
    } 
    return null; 
} 
public static void destroyConnection() { 
    try { 
     if(stmt != null) 
     stmt.close(); 
     if(con!= null) 
     con.close(); 
     connectionMade = false; 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

完整的堆栈跟踪:

[9/07/15 19:23]: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure 

Last packet sent to the server was 10 ms ago. 
[9/07/15 19:23]:  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
[9/07/15 19:23]:  at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) 
[9/07/15 19:23]:  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) 
[9/07/15 19:23]:  at java.lang.reflect.Constructor.newInstance(Unknown Source) 
[9/07/15 19:23]:  at com.mysql.jdbc.Util.handleNewInstance(Util.java:406) 
[9/07/15 19:23]:  at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1074) 
[9/07/15 19:23]:  at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2985) 
[9/07/15 19:23]:  at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2871) 
[9/07/15 19:23]:  at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3414) 
[9/07/15 19:23]:  at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1936) 
[9/07/15 19:23]:  at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2060) 
[9/07/15 19:23]:  at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2536) 
[9/07/15 19:23]:  at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1564) 
[9/07/15 19:23]:  at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1485) 
[9/07/15 19:23]:  at server.util.SQL.query(SQL.java:29) 
[9/07/15 19:23]:  at server.util.SQL.saveHighScore(SQL.java:55) 
[9/07/15 19:23]:  at server.model.mobile.players.Client.logout(Client.java:581) 
[9/07/15 19:23]:  at server.model.mobile.players.packets.Clicking.ClickingButtons.processPacket(ClickingButtons.java:2190) 
[9/07/15 19:23]:  at server.model.mobile.players.PacketHandler.processPacket(PacketHandler.java:118) 
[9/07/15 19:23]:  at server.model.mobile.players.Client.processQueuedPackets(Client.java:769) 
[9/07/15 19:23]:  at server.model.mobile.players.PlayerHandler.process(PlayerHandler.java:191) 
[9/07/15 19:23]:  at server.Server$1.execute(Server.java:103) 
[9/07/15 19:23]:  at server.task.Task2.tick(Task2.java:105) 
[9/07/15 19:23]:  at server.event.TaskScheduler.run(TaskScheduler.java:100) 
[9/07/15 19:23]:  at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) 
[9/07/15 19:23]:  at java.util.concurrent.FutureTask.runAndReset(Unknown Source) 
[9/07/15 19:23]:  at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(Unknown Source) 
[9/07/15 19:23]:  at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source) 
[9/07/15 19:23]:  at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
[9/07/15 19:23]:  at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
[9/07/15 19:23]:  at java.lang.Thread.run(Unknown Source) 
[9/07/15 19:23]: Caused by: java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost. 
[9/07/15 19:23]:  at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2431) 
[9/07/15 19:23]:  at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2882) 
[9/07/15 19:23]:  ... 24 more 
[9/07/15 19:23]: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure 
Last packet sent to the server was 10 ms ago. 
[9/07/15 19:23]:  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
[9/07/15 19:23]:  at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) 
[9/07/15 19:23]:  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) 
[9/07/15 19:23]:  at java.lang.reflect.Constructor.newInstance(Unknown Source) 
[9/07/15 19:23]:  at com.mysql.jdbc.Util.handleNewInstance(Util.java:406) 
[9/07/15 19:23]:  at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1074) 
[9/07/15 19:23]:  at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2985) 
[9/07/15 19:23]:  at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2871) 
[9/07/15 19:23]:  at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3414) 
[9/07/15 19:23]:  at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1936) 
[9/07/15 19:23]:  at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2060) 
[9/07/15 19:23]:  at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2536) 
[9/07/15 19:23]:  at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1564) 
[9/07/15 19:23]:  at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1485) 
[9/07/15 19:23]:  at server.util.SQL.query(SQL.java:29) 
[9/07/15 19:23]:  at server.util.SQL.saveHighScore(SQL.java:55) 
[9/07/15 19:23]:  at server.model.mobile.players.Client.logout(Client.java:581) 
[9/07/15 19:23]:  at server.model.mobile.players.packets.Clicking.ClickingButtons.processPacket(ClickingButtons.java:2190) 
[9/07/15 19:23]:  at server.model.mobile.players.PacketHandler.processPacket(PacketHandler.java:118) 
[9/07/15 19:23]:  at server.model.mobile.players.Client.processQueuedPackets(Client.java:769) 
[9/07/15 19:23]:  at server.model.mobile.players.PlayerHandler.process(PlayerHandler.java:191) 
[9/07/15 19:23]:  at server.Server$1.execute(Server.java:103) 
[9/07/15 19:23]:  at server.task.Task2.tick(Task2.java:105) 
[9/07/15 19:23]:  at server.event.TaskScheduler.run(TaskScheduler.java:100) 
[9/07/15 19:23]:  at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) 
[9/07/15 19:23]:  at java.util.concurrent.FutureTask.runAndReset(Unknown Source) 
[9/07/15 19:23]:  at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(Unknown Source) 
[9/07/15 19:23]:  at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source) 
[9/07/15 19:23]:  at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
[9/07/15 19:23]:  at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
[9/07/15 19:23]:  at java.lang.Thread.run(Unknown Source) 
[9/07/15 19:23]: Caused by: java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost. 
[9/07/15 19:23]:  at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2431) 
[9/07/15 19:23]:  at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2882) 
[9/07/15 19:23]:  ... 24 more 
+0

根本原因似乎是java.io.EOFException:无法读取服务器的响应。预计会读取4个字节,在连接意外丢失之前读取0个字节。也许[这可以帮助](http://stackoverflow.com/questions/13950496/what-is-java-io-eofexception-message-can-not-read-response-from-server-expect) – MadProgrammer

+0

由于'createConnection'不会出现在堆栈跟踪中,可能是因为您正在使用已关闭的陈旧“Connection”... – MadProgrammer

+0

我能做些什么来解决它? @MadProgrammer – Joliquine4

回答

1

一般来说,看来ConnectionStatement你是依靠已经关闭,要么明确是自己或隐式地由服务器。

作为一般的好习惯,你应该只创建一个新的Statement,当你需要它,关闭它,当你正在做的,例如...

public Connection createConnection() throws SQLException { 
    Connection con = null; 
    try { 
     Class.forName("com.mysql.jdbc.Driver").newInstance(); 
     con = DriverManager.getConnection("jdbc:mysql://localhost/highscores", "root", "root"); 
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException ex) { 
     throw new SQLException("Unable to load JDBC driver", ex); 
    } 
    return con; 
} 

public void makeQuery() throws SQLException { 

    try (Connection con = createConnection()) { 
     try (PreparedStatement stmt = con.prepareStatement("...")) { 
      // Fill in parameters to the statement 
      try (ResultSet rs = stmt.executeQuery()) { 
       while (rs.next()) { 
        // Get the results 
       } 
      } 
     } 
    } 

} 

最佳做法还建议你利用PreparedStatement s确保你的代码不会成为SQL注入攻击的受害者

查看The try-with-resources StatementUsing Prepared Statements了解更多详情。

我还鼓励您对连接池进行一些研究,因为这将有助于节省创建多个连接并帮助管理其生命周期的时间。

我也会小心使用static,因为这会增加线程问题的风险,让一个线程在另一个线程尝试使用它时关闭连接。

+0

非常感谢。我的代码现在符合你的建议(无论如何),它似乎运作良好。 @MadProgrammer – Joliquine4