问题
I've hosted a MySQL DB in a webserver. I've granted all privledges and allowed my IP to connect to this database remotely from my local computer. It gets connected and I'm able to retrieve data from the database to my Java Swing application. But, sometimes I get this error message and my connection with the hosted DB fails. Error is shows below:
Apr 7, 2012 12:49:20 AM scm.new_fas txtSearchKeyReleased
SEVERE: null
com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception:
** BEGIN NESTED EXCEPTION **
java.io.EOFException
MESSAGE: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
STACKTRACE:
java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1997)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2411)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2916)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1631)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1723)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3250)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3179)
at com.mysql.jdbc.Statement.executeQuery(Statement.java:1207)
at scm.DBControl.getResult(DBControl.java:49)
at scm.new_fas.txtSearchKeyReleased(new_fas.java:1686)
at scm.new_fas.access$2300(new_fas.java:28)
at scm.new_fas$23.keyReleased(new_fas.java:1136)
at java.awt.Component.processKeyEvent(Component.java:5999)
at javax.swing.JComponent.processKeyEvent(JComponent.java:2794)
at java.awt.Component.processEvent(Component.java:5815)
at java.awt.Container.processEvent(Container.java:2058)
at java.awt.Component.dispatchEventImpl(Component.java:4410)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1848)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:693)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:958)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:830)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:657)
at java.awt.Component.dispatchEventImpl(Component.java:4282)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Window.dispatchEventImpl(Window.java:2429)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
** END NESTED EXCEPTION **
Last packet sent to the server was 2 ms ago.
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2622)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2916)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1631)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1723)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3250)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3179)
at com.mysql.jdbc.Statement.executeQuery(Statement.java:1207)
at scm.DBControl.getResult(DBControl.java:49)
at scm.new_fas.txtSearchKeyReleased(new_fas.java:1686)
at scm.new_fas.access$2300(new_fas.java:28)
at scm.new_fas$23.keyReleased(new_fas.java:1136)
at java.awt.Component.processKeyEvent(Component.java:5999)
at javax.swing.JComponent.processKeyEvent(JComponent.java:2794)
at java.awt.Component.processEvent(Component.java:5815)
at java.awt.Container.processEvent(Container.java:2058)
at java.awt.Component.dispatchEventImpl(Component.java:4410)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1848)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:693)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:958)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:830)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:657)
at java.awt.Component.dispatchEventImpl(Component.java:4282)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Window.dispatchEventImpl(Window.java:2429)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
Can somebody please help me with this situation. I dont understand whats wrong! Is it the server or ? Thanks a lot :)
This is my class to Connect the DB:
package scm;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class DBControl {
private static DBControl con;
private static String severIp = null;
private static String severPort = null;
private static String userName = null;
private static String password = null;
private static ResultSet rs = null;
private static Connection cc = null;
public DBControl() {
}
public static synchronized DBControl getInstance() {
if (con == null) {
con = new DBControl();
}
return con;
}
public void setSeverIp(String Ip) {
severIp = Ip;
}
public void setSeverPort(String Port) {
severPort = Port;
}
public void SetUserName(String Name) {
userName = Name;
}
public void setPassword(String passWord) {
password = passWord;
}
public static ResultSet getResult(String url) throws Exception {
Statement s = cc.createStatement();
rs = s.executeQuery(url);
return rs;
}
public static Connection getConnection() throws Exception {
// try {
Class.forName("com.mysql.jdbc.Driver");
cc = (Connection) DriverManager.getConnection("jdbc:mysql://" + getSeverIp() + ":" + getSeverPort() + "/anuradha_rr", getUserName(), getPassword());
return cc;
}
public void setResult(String url) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
cc = (Connection) DriverManager.getConnection("jdbc:mysql://" + getSeverIp() + ":" + getSeverPort() + "/anuradha_rr", getUserName(), getPassword());
Statement s = (Statement) cc.createStatement();
s.executeUpdate(url);
}
public static String getSeverIp() {
return severIp;
}
public static String getSeverPort() {
return severPort;
}
public static String getUserName() {
return userName;
}
public static String getPassword() {
return password;
}
}
回答1:
Make sure you are not using a dead jdbc connection. Depending on how you are creating your jdbc connection they may be going idle. If you are using the same connection over and over, test the connection before you try to issue a query and get a new one if it has been closed by mysql.
UPDATE:
You create a new connection everywhere except getResult() which is where the stack trace identifies the error comes from. You can either create a new connection like you do everywhere else, or improve the encapsulation of getConnection(). In other words, change getConnection() to return the static Connection stored in your class, on condition it is not null and still valid. Otherwise create a new connection and return that.
回答2:
This is a fairly common problem in MySQL, unfortunately occurring usually only after in production when application runs for some extended time unlike in the short development cycle.
MySQL closes connections without notifying its clients and the not much telling exception is what appears when you try to use a timed out connection. you could for example ping the connection with some trivial SQL statement periodically to avoid timeout.
It is a good practice to use a connection pool (to avoid problem with too many users accessing the DB at once), e.g. DBCP, in general. DBCP may be added to your application easily and you only set it as a quasi JDBC driver. There you can set things proper way.
I copied this DBCP config from one of my projects:
MaxActive=20,
MaxWait=60000,
TestWhileIdle=true,
TimeBetweenEvictionRunsMillis=300000,
MinEvictableIdleTimeMillis=300000,
TestOnBorrow=true,
ValidationQuery='SELECT 1'
Update: As a very simple solution, you could try catching the exception on access and open a new connection in that case.
来源:https://stackoverflow.com/questions/10048296/error-in-mysql-connection-when-accessing-a-remote-server