封闭连接:java中的下一个

我有ResultSet方法,我在一个finallly块中关闭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 

我做得不对劲?

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

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

  1. 打开连接
  2. 准备一份声明
  3. 获取结果集
  4. 返回结果集
  5. 关闭连接(可能会关闭相关资源,即它可能会关闭PreparedStatement和与当前Connection关联的ResultSet ),因为,如前面的链接中所述, finally始终至少执行JVM崩溃或您手动完成使用System.exit应用程序。
  6. 使用关闭的ResultSet 。 由于上一步骤,它已关闭。

一个可能的解决方案是你的countdrcountcr方法和返回ResultSet所有其他方法都接收Connection as参数,因此调用它的方法将处理连接打开和关闭。 另外,请注意,如果您在multithreading环境(例如Web应用程序)中工作,则不应使用static方法来处理数据库操作。

你正在关闭你的finally块中的底层Connection …你没有关闭PreparedStatement(你应该,但你需要在使用ResultSet之后关闭它)。 使用调用者的finally块(打开Connection )。 此外,您可能需要考虑使用setFetchSize() 。

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

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

检查应用程序上下文xml文件以获取参数removeAbandonedTimeout值。

removeAbandonedTimeout = 300

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

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

如果你试图关闭while块内的连接,那时候你也可以得到这种exception……所以关闭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(); } } } 

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

这真的有帮助。