java - JDBC 连接太多 - 连接已正确关闭

标签 java mysql jdbc connection

我讨厌提出一个在网络上被广泛询问的问题,但我似乎无法解决它。 我正确关闭了所有连接,但程序抛出“连接异常过多”

这是我的连接助手

 public MySQLConnection() {
    try {

      // Datenbanktreiber für ODBC Schnittstellen laden.
      // Für verschiedene ODBC-Datenbanken muss dieser Treiber
      // nur einmal geladen werden.
      Class.forName("com.mysql.jdbc.Driver");

      // Verbindung zur ODBC-Datenbank 'sakila' herstellen.
      // Es wird die JDBC-ODBC-Brücke verwendet.
      conn = DriverManager.getConnection("jdbc:mysql://" + dbHost + ":"
          + dbPort + "/" + database + "?" + "user=" + dbUser + "&"
          + "password=" + dbPassword);
    } catch (ClassNotFoundException e) {
      System.out.println("Treiber nicht gefunden");
    } catch (SQLException e) {
      System.out.println("Connect nicht moeglich"+e);
    }
  }

  public Connection getInstance()
  {

    if(conn == null)
      new MySQLConnection();
    return conn;
  }


  public final void close_multiple( final Connection con, final ArrayList<PreparedStatement> listPreparedstatments, final ArrayList<ResultSet> listResultsets )
  {
      try
      {
          if ( con != null && con.isClosed())
          {
              con.close();

          }
          for(PreparedStatement pstm : listPreparedstatments)
              if ( pstm != null && pstm.isClosed())
              {
                  pstm.close();
              }
          for(ResultSet rs : listResultsets){
              if ( rs != null && rs.isClosed())
              {
                  rs.close();
              }
          }

      }
      catch ( SQLException e )
      {
          e.printStackTrace();
      }
  }

  public final void close_single( final Connection con, final PreparedStatement stmt, final ResultSet rs )
  {
      try
      {
          if( con != null && con.isClosed())
          {
              con.close();
          }
          if ( stmt != null && stmt.isClosed())
          {
              stmt.close();
          }
          if ( rs != null && rs.isClosed())
          {

            rs.close();
          }

      }
      catch ( SQLException e )
      {
          e.printStackTrace();
      }
  }

这里有一些示例代码

 public ArrayList<Product_Type> getProduct_Types() throws JSONException {
      conn = mysqlconnection.getInstance();
      Product_Type product_type;
      ArrayList<Product_Type> listProduct_Types = new ArrayList<Product_Type>();
      if(conn != null){
          //MYSQL Resultsets and Statements
          ResultSet rst_product_type=null;
          PreparedStatement pstmt_product_type=null;
          try{

            String sql = "SELECT * FROM `product_type`";
            pstmt_product_type = conn.prepareStatement(sql);
            rst_product_type = pstmt_product_type.executeQuery();

            while(rst_product_type.next()) { 
                product_type = new Product_Type();
                product_type.setProduct_Type_ID(rst_product_type.getInt("Product_Type_ID"));
                product_type.setProduct_Type_Name(rst_product_type.getString("Product_Type_Name")); 
                listProduct_Types.add(product_type);
            }
         } catch(Exception e){
            System.out.println("Unable to connect to product_type Table.");
         } finally {
             mysqlconnection.close_single(conn, pstmt_product_type, rst_product_type);
         }
      }
      return listProduct_Types; 
  }

  public ArrayList<Product_Type> getProduct_Type_by_Manufacturer_ID(int manufacturer_id) throws JSONException, SQLException {
        conn = mysqlconnection.getInstance();
        Product_Type product_type;
        ArrayList<Product_Type> listProduct_Types = new ArrayList<Product_Type>();
        ArrayList<ResultSet> listResultsets = new ArrayList<ResultSet>();
        ArrayList<PreparedStatement> listPreparedstatments = new ArrayList<PreparedStatement>();

         if(conn != null){
             PreparedStatement pstmt_product_detail = null;
             PreparedStatement pstmt_product_type = null;

             ResultSet rst_product_type = null;
             ResultSet rst_product_detail = null;
             try{                       
                    String sql_product_detail = "SELECT DISTINCT(Product_Type_ID) FROM `product_details` WHERE Manufacturer_ID=?"; 
                    pstmt_product_detail = conn.prepareStatement(sql_product_detail);
                    pstmt_product_detail.setInt(1, manufacturer_id);
                    rst_product_detail = pstmt_product_detail.executeQuery();

                    while(rst_product_detail.next()) { 
                         String sql_product_type = "SELECT Product_Type_ID, Product_Type_Name FROM `product_type` WHERE Product_Type_ID=?";
                         pstmt_product_type = conn.prepareStatement(sql_product_type);
                         pstmt_product_type.setInt(1, rst_product_detail.getInt("Product_Type_ID"));
                         rst_product_type = pstmt_product_type.executeQuery();

                         while(rst_product_type.next()) { 
                             product_type = new Product_Type();
                             product_type.setProduct_Type_ID(rst_product_type.getInt("Product_Type_ID"));
                             product_type.setProduct_Type_Name(rst_product_type.getString("Product_Type_Name"));    
                             listProduct_Types.add(product_type);
                        }
                     }
                    listPreparedstatments.add(pstmt_product_type);
                    listPreparedstatments.add(pstmt_product_detail);
                    listResultsets.add(rst_product_detail);
                    listResultsets.add(rst_product_type);
             } catch(Exception e){
                System.out.println("Unable to connect to pr Table.");
             } finally {
                 //Close MYSQL-Connection
                 mysqlconnection.close_multiple(conn, listPreparedstatments, listResultsets);
             }
         }

         return listProduct_Types;
  }

我不明白问题出在哪里?我还尝试增加 mysql 最大连接数,但它仍然无法正常工作

最佳答案

您实际上根本没有关闭连接(以及 ResultSets 和 PreparedStatements),仅当连接已经关闭时才会调用此代码中的 con.close():

if (con != null && con.isClosed()) {
    con.close();
}

它可能应该是 !con.isClosed()

这似乎是主要问题。但是,正如 John Skeet 在问题评论中提到的,您的代码中还存在其他问题。

关于java - JDBC 连接太多 - 连接已正确关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27642285/

相关文章:

java - 防止并发回调代码运行两次

mysql - 选择 Mariadb 中除顶行之外的所有行

php - 根据 PHP 时间戳过滤数据

java - 如何使用Java更新aes加密

Tomcat JDBC 池指标

java - 在 tomcat 7 上部署 Spring Boot War 时出现问题

java - 我可以只使用一张表进行所有 hibernate 环境审计吗?

java - 我希望这段代码从 android studio 循环

php - 确定是否安装了多个 MySQL 服务器

java - 尝试运行 alter session 命令通过 JDBC 设置 session 变量