封闭连接:java中的下一个

时间:2013-12-10 15:00:34

标签: java jdbc

我有ResultSet方法,我正在关闭Connection中的一个块:

 public static ResultSet countdrcountcr(String vforacid) throws SQLException {
        ResultSet rs = null;
        Connection conn = null;
        try {

            conn = db.getDbConnection();
            String sql = "SELECT NVL (SUM (DECODE (part_tran_type, 'D', 1, 0)), 0), "
                    + " NVL (SUM (DECODE (part_tran_type, 'C', 1, 0)), 0) "
                    + " FROM tbaadm.htd WHERE acid IN (SELECT acid "
                    + " FROM tbaadm.gam WHERE foracid = '" + vforacid + "') "
                    + " AND tran_date >= '22-NOV-2013'  AND tran_date <= '30-NOV-2013' "
                    + " AND pstd_flg = 'Y' AND del_flg != 'Y'";
            PreparedStatement ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();

            return rs;
        } finally {
            conn.close();
        }
    }

但我收到错误:

编辑整个ErrorTrace

Exception in thread "main" java.sql.SQLException: Closed Connection: next
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)
at oracle.jdbc.driver.OracleResultSetImpl.next(OracleResultSetImpl.java:181)
at statement.Statement.main(Statement.java:34)
Java Result: 1

我做得不对?

7 个答案:

答案 0 :(得分:8)

您将返回ResultSet以供将来使用,但在使用它之后您将关闭连接,因此您无法检索数据,因为资源已关闭。请注意,即使您在finallytry代码块中返回某些内容,也始终会调用catch,请参阅Does finally always execute in Java?

详细地说,这就是问题所在:

  1. 打开连接
  2. 准备声明
  3. 获取结果集
  4. 返回结果集
  5. 关闭连接(可能会关闭相关资源,即可能会关闭与当前PreparedStatement关联的ResultSetConnection),因为如之前的链接中所述,{ {1}}阻止始终至少执行JVM崩溃或您使用finally手动完成应用程序。
  6. 使用已关闭的System.exit。它由于上一步而关闭。
  7. 一种可能的解决方案是,您的ResultSet方法和返回countdrcountcr的所有其他方法都会收到ResultSet作为参数,因此调用它的方法将处理连接打开和收盘。另外,请注意,如果您在多线程环境中工作,则不应使用Connection方法来处理数据库操作,例如:一个Web应用程序。

答案 1 :(得分:1)

我认为您的查询需要很长时间才能执行并被驱动程序/ tomcat级别终止。

检查应用程序上下文xml文件中的参数 removeAbandonedTimeout 值。

removeAbandonedTimeout = 300

表示如果jdbc驱动程序将关闭运行300秒以上的任何查询。这样做是为了避免连接池“泄漏”。要解决此问题,您可以使用更高的数字设置值。

有关此参数及其他相关参数的详细信息,请参见here

答案 2 :(得分:0)

你正在关闭你的finally块中的基础Connection ...你没有关闭PreparedStatement(你应该,但你需要在使用ResultSet之后关闭它) 。使用调用者的finally块(打开Connection的地方)。另外,您可能需要考虑使用setFetchSize()

答案 3 :(得分:0)

您无法关闭Connection,然后使用ResultSet。您必须先完成ResultSet的使用,然后再关闭Connection。正常模式是首先使用ResultSet完成工作,通常在“数据访问对象”中,并将数据的一些封装表示作为对象返回。

答案 4 :(得分:0)

如果你试图关闭while块内的连接那段时间也可以得到这种异常......所以关闭while块之后的连接

package com.literals;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class DataBaseDemo {

    public static void main(String[] args) {
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
            System.out.println("driver is loading...........");
            Connection con=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:mytest","SYSTEM","murali");
            System.out.println("connection is established");
            Statement st=con.createStatement();
            System.out.println("statement is created");

            ResultSet rs=st.executeQuery("select * from student");
            while(rs.next()){
                System.out.println(rs.getString(1)+"          "+rs.getInt(2)+"          "+rs.getString(3)+"");
                con.close();

            }


        } catch (ClassNotFoundException | SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();

        }





    }

}

答案 5 :(得分:0)

如上所述:另外,请注意,如果您在多线程环境中工作,则不应使用静态方法来处理数据库操作,例如:一个Web应用程序。

真的有帮助。

答案 6 :(得分:0)

我有一个类似的问题,其中我的连接在while循环内被关闭,因此在下一轮无法检查条件。为了解决这个问题,我将con.close();放在了循环之外,这解决了这个问题。像这样:

    while (rs.next()) {
    String name = rs.getString("NAME");
    }
    con.close(); //placed outside the loop
}