0

こんにちは私はjspプロジェクトをやっています。プロジェクトをApache Tomcatにデプロイします。私はmysqlをデータベースとして使用しています。

プロジェクトをリモートサーバーにデプロイすると、正常に実行されます。しかし、数時間後にSQLエラーが発生します。次に、Apache サーバーに戻り、projecet を再度開始すると、数時間後に同じ SQL エラーが再び発生します。私は問題を知りません。それは私のJava接続コードが原因なのか、それともmysqlサーバーに関するものなのか. なぜSQLエラーが発生するのか教えてもらえますか?

public class ConnectionManager {

    private String className = "com.mysql.jdbc.Driver";
    private String userName ="username";
    private String password = "password";
    private String url = "jdbc:mysql://localhost:3306/database?useUnicode=true&characterEncoding=utf-8";
    /**
     * @uml.property  name="connectionInstance"
     * @uml.associationEnd  
     */
    private static ConnectionManager connectionInstance = null;

  public ConnectionManager(){

  }

  public static synchronized ConnectionManager getInstance() {
    if(connectionInstance == null) {
      connectionInstance = new ConnectionManager();         
    }
    return connectionInstance;
  }

  public Connection getConnection(){

      Connection conn = null;
      try {
          Class.forName(className);
          conn = DriverManager.getConnection (url, userName, password);
          System.out.println("Connection Established");
      }  catch (ClassNotFoundException e) {
          e.printStackTrace();
      }  catch (SQLException e) {
          e.printStackTrace();
      }
      return conn;
  }
4

2 に答える 2

1

MySQL のデフォルトの接続タイムアウトは 8 時間です。したがって、これは、SQL 接続を開いたままにしておく時間が長すぎることを意味します。あなたのコードは、アプリケーションの起動時に接続を 1 つだけ作成し、それをアプリケーション全体で再利用していることを示唆しています。これは非常に悪いです。これはスレッドセーフではありません。

コード内のどこConnectionにも SQLを静的変数またはインスタンス変数として宣言および格納しないように、コードを変更する必要があります。代わりに、可能な限り短いスコープ内で宣言、作成、およびクローズする必要があります。できれば、SQL クエリを実行している場所とまったく同じメソッド ブロック内に配置します。

ConnectionManagerこれは、適切に仕事をするあなたのマイナーな書き直しです:

public class ConnectionManager {

    private static final String DRIVER = "com.mysql.jdbc.Driver";
    private static final String USERNAME ="username";
    private static final String PASSWORD = "password";
    private static final String URL = "jdbc:mysql://localhost:3306/database?useUnicode=true&characterEncoding=utf-8";

    static {
        try {
            Class.forName(DRIVER);
        }
        catch (ClassNotFoundException e) {
            throw new ExceptionInInitializerError(DRIVER + " missing in classpath!", e);
        }
    }

    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(URL, USERNAME, PASSWORD);
    }
}

次のように使用します。

public class SomeDAO {

    public SomeEntity find(Long id) throws SQLException {
        Connection connection = null;
        // ...

        try {
            connection = ConnectionManager.getConnection();
            // ...
        }
        finally {
            // ...
            if (connection != null) try { connection.close(); } catch(SQLException ignore) {}
        }

        return someEntity;
    }

接続パフォーマンスを向上させるには、 の代わりに接続プールを使用しますDriverManager

以下も参照してください。

于 2012-04-26T13:46:29.737 に答える
0

それらを使用した後、接続を適切に閉じていますか。

于 2012-04-26T09:56:25.760 に答える