2015-07-13 61 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