【问题标题】:Connection Closed even when the connection is closed below the code即使连接在代码下方关闭,连接也已关闭
【发布时间】:2014-07-20 14:28:13
【问题描述】:

我在下面有一个基本代码 sn-p 但它不起作用。它可能是什么问题。

public List<String> getStores() throws SQLException{
        List<String> store_id=new ArrayList<>();
        String query="select distinct(store_id) from stores";
        Connection con=ConnectDatabase.getDb2ConObj();
        Statement stmt=con.createStatement();
        java.sql.ResultSet rsResultSet=stmt.executeQuery(query);
        while(rsResultSet.next()){
            store_id.add(rsResultSet.getString(1));
        }
        con.close();
        return store_id;
    }

抛出以下异常

com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: No operations allowed after connection closed.
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:888)
    at com.mysql.jdbc.Connection.checkClosed(Connection.java:1931)
    at com.mysql.jdbc.Connection.createStatement(Connection.java:3087)
    at com.mysql.jdbc.Connection.createStatement(Connection.java:3069)
    at com.dao.StoreDao.getStores(StoreDao.java:52)
    at org.apache.jsp.adminViewAllStore_jsp._jspService(adminViewAllStore_jsp.java:119)

ConnectDatabse 的代码是

public class ConnectDatabase {
     static Connection con=null;
     static String connectionString="jdbc:mysql://localhost:3306/ayurveda";
     static String username="root";
     static String password="";
     public static Connection getDb2ConObj(){
         if(con==null){
         try{
             Class.forName("com.mysql.jdbc.Driver");
             con=DriverManager.getConnection(connectionString,username,password);
         }
         catch(ClassNotFoundException | SQLException e)
         {
             System.out.println("Connect initialized with error"+e.getMessage());
             e.printStackTrace();
         }
         }
         return con;
     }

我无法理解相同的原因。可能是什么问题。因为我在完成连接后关闭了连接。

【问题讨论】:

  • 你得到了对象,却没有打开连接?
  • ConnectDatabase 是什么?
  • 您可能正在将您的连接缓存在ConnectDatabase.getDb2ConObj() 中,然后在下次调用此方法时返回相同的连接?您最好使用连接池,而不是尝试维护自己的连接池。请发布ConnectDatabase的代码,我们可以确认。
  • 嗨,已编辑问题

标签: java mysql database-connection


【解决方案1】:

在我将它包含在 try catch finally 块中后它起作用了。更改了下面给出的代码

public List<String> getStores() throws SQLException{
        List<String> store_id=new ArrayList<>();
        Connection con=ConnectDatabase.getDb2ConObj();
        try{
        String query="select distinct(store_id) from stores";
        Statement stmt=con.createStatement();
        java.sql.ResultSet rsResultSet=stmt.executeQuery(query);
        while(rsResultSet.next()){
            store_id.add(rsResultSet.getString(1));
        }
        }catch(Exception e){

        }finally{
            con.close();
        }
        return store_id;
    }

谢谢。

【讨论】:

  • 首先,这不是处理错误的好方法。第二,你现在真的得到数据了吗?
  • 嗨 Bart.Yes 在对象中我已经定义了语句
  • Class.forName("com.mysql.jdbc.Driver"); con=DriverManager.getConnection(connectionString,username,password);
【解决方案2】:

您可以使用这种类型的代码...解决您的问题

     public void actionPerformed(ActionEvent ae)
     {
     String u=t1.getText();
     String p=t2.getText();
    if(ae.getSource()==b1)
     {
      try{
     Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
     Connection con=DriverManager.getConnection("jdbc:odbc:newdsn");

      String stp="SELECT * FROM reg";
      Statement sa=con.createStatement();
      rs=sa.executeQuery(stp);
     while(rs.next())
      {
       String du=rs.getString(2);
       String dp=rs.getString(3);
       if(du.equals(u)&&dp.equals(p))
      {
       a=0;
     break;
     }else{ a=1;}
       }
     if(a==0){
     JOptionPane.showMessageDialog(this,"LOGIN PAGE","Login is successful",1);
       }
      if(a==1){

      JOptionPane.showMessageDialog(this,"LOGIN PAGE","Login is not successful",1);

      }}    
      catch(Exception e){}
      }}

如果它甚至抛出异常然后你检查系统 32 位或 64 位..你应该尝试如果 64 位那么请让你的 dsn 为 32 位并使用 ms 访问 2002-2003 版本
然后你得到旅游解决方案.....谢谢你

【讨论】:

    【解决方案3】:

    使用Java 7 -The try-with-resources Statement

    根据oracle documentation,您可以将 try-with-resources 块与常规 try 块结合起来

    典型的 Java 应用程序处理多种类型的资源,例如文件、流、套接字和数据库连接。此类资源必须非常小心地处理,因为它们会获取系统资源来进行操作。因此,您需要确保即使出现错误也能释放它们

    确实,不正确的资源管理是生产应用程序中常见的故障来源,通常的缺陷是数据库连接,并且在代码中的其他地方发生异常后文件描述符仍然处于打开状态。这会导致应用服务器在资源耗尽时频繁重启,因为操作系统和服务器应用程序一般都有资源上限。

    示例代码:

    try(Connection con = getConnection()) {
       ...
    }
    

    阅读更多Java 7 Automatic Resource Management JDBC


    • 同时关闭StatementResultSet

    • 不要在每次需要连接时都加载驱动程序类。只需在静态初始化块中加载一次。

      static {
          try {
              Class.forName("com.mysql.jdbc.Driver");
          } catch (ClassNotFoundException e) {
              e.printStackTrace();
          }
      }
      
    • 我建议您使用JNDIDataSource 将用户名和密码保留在Java 代码之外,以使其更易于管理。将数据库配置保存在单独的 xml/properties 文件中,而不是 Java 文件中的硬编码

      参见Connecting with DataSource Objects上的Java 教程

      我已经发布了一个很好的ConnectionUtil 类来管理整个应用程序的单个类中的所有连接。

    【讨论】:

    • 比起我更喜欢你的回答。
    • 在 Java 6 中,关闭资源的工作更繁琐,但在 Java 7 中处理。
    • 在java 7中你不需要关闭它会自动关闭的资源。
    猜你喜欢
    • 1970-01-01
    • 2012-09-29
    • 2020-09-16
    • 1970-01-01
    • 2016-07-18
    • 1970-01-01
    • 2013-05-31
    • 1970-01-01
    相关资源
    最近更新 更多