2012-04-06 4 views
3

웹 서버에 호스팅했습니다. 나는 모든 허가를 부여하고 내 IP가 내 로컬 컴퓨터에서 원격으로이 데이터베이스에에 연결할 수 있도록했습니다. 연결된 상태가되어 데이터베이스에서 Java Swing 응용 프로그램으로 데이터를 검색 할 수 있습니다. 그러나 때로는 이 오류 메시지가 발생합니다.호스트 DB와의 연결에 실패했습니다. 이다 오류가 아래에 보여줍니다원격 서버에 액세스 할 때 MySQL 연결에 오류가 발생했습니다

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) 

누군가가이 상황을 좀 도와 주시겠습니까. 나는 틀린 것을 이해하지 않는다! 서버입니까? 고마워요 :)

이것은 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; 
    } 
} 

답변

3

당신이 죽은 JDBC 연결을 사용하지 않는 있는지 확인합니다. jdbc 연결을 작성하는 방법에 따라 유휴 상태가 될 수 있습니다. 계속해서 동일한 연결을 사용하고 있다면 쿼리를 실행하기 전에 연결을 테스트하고 mysql에 의해 닫혀진 쿼리를 새로 받으십시오.

UPDATE :

당신은 getResult를 (제외한 모든 새 연결을 만들) 스택 추적 오류에서 오는 식별 곳입니다. 다른 곳과 같이 새 연결을 만들거나 getConnection()의 캡슐화를 향상시킬 수 있습니다. 다시 말해 getConnection()을 변경하여 클래스에 저장된 정적 Connection을 반환합니다.이 Connection은 null이 아니며 여전히 유효합니다. 그렇지 않으면 새 연결을 만들어 반환하십시오.

+0

팁 주셔서 감사합니다. 그러나 나는 그것을 어떻게합니까? – wishman

+0

연결을 직접 호출하거나 데이터베이스 추상화 도구를 사용하고 있습니까? java.sql.Connection을 직접 호출하는 경우 isValid (int timeout) 메소드를 사용해보십시오. – Dave

+0

방금 ​​내 질문을 편집하고 클래스를 추가하여 DB에 연결했습니다. 너는 그걸 확인하고 내가 어디에서 그것을 시정해야하는지 말해 줄 정도로 친절 해 주실 수 있겠습니까? 고마워요 :) – wishman

2

이것은 MySQL에서 상당히 일반적으로 발생하는 문제입니다. 일반적으로 짧은 개발주기와 달리 응용 프로그램이 약간의 시간 동안 실행될 때만 프로덕션 환경에서 발생합니다.

MySQL은 클라이언트에 통지하지 않고 연결을 닫습니다. 예외가 발생하면 제한 시간 초과 연결을 사용하려고 할 때 표시되는 예외가 있습니다. 당신은 예를 들어 타임 아웃을 피하기 위해주기적인 SQL 문으로 주기적으로 ping을 할 수 있습니다.

연결 풀을 사용하는 것이 좋습니다 (너무 많은 사용자가 동시에 DB에 액세스하는 문제를 방지하기 위해). 일반적으로 DBCP. DBCP는 응용 프로그램에 쉽게 추가 될 수 있으며 준 JDBC 드라이버로 만 설정할 수 있습니다. 여기에서 적절한 방법으로 설정할 수 있습니다. 당신은 액세스에 대한 예외를 잡기 시도하고 경우에 새로운 연결을 열 수있는 매우 간단한 해결책으로 :

    MaxActive=20, 
       MaxWait=60000, 
       TestWhileIdle=true, 
       TimeBetweenEvictionRunsMillis=300000, 
       MinEvictableIdleTimeMillis=300000, 
       TestOnBorrow=true, 
       ValidationQuery='SELECT 1' 

업데이트 :

나는 내 프로젝트 중 하나에서이 DBCP의 설정을 복사.

관련 문제