Closed Connection:Java中的下一个

问题描述 投票:3回答:6

我有ResultSet方法,将要在最后一个块中关闭连接:

 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

我在做什么不好?

java jdbc
6个回答
8
投票

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

详细来说,这是问题所在:

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

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

    检查您的应用程序上下文XML文件中的参数

    removeAbandonedTimeout值。

    removeAbandonedTimeout = 300

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

    有关此参数和其他相关参数的更多信息,请参见here


    0
    投票
    [您要在您的finally块中关闭底层的Connection ...您没有要关闭PreparedStatement(并且应该关闭,但是在使用ResultSet之后也需要关闭它)。使用调用者的finally块(在其中打开Connection)。另外,您可能要考虑使用setFetchSize()

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

    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(); } } }


    0
    投票
    [就像上面说的:另外,请注意,如果您在多线程环境中工作,例如,不应该使用静态方法来处理数据库操作。网络应用程序。

    真的有帮助。

    © www.soinside.com 2019 - 2024. All rights reserved.