封闭连接: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
以供将来使用,但在使用它之后您将关闭连接,因此您无法检索数据,因为资源已关闭。 请注意,即使您在try
或catch
代码块中返回某些内容,也始终会调用finally
,请参阅最终是否始终在Java中执行?
详细地说,这是问题所在:
- 打开连接
- 准备一份声明
- 获取结果集
- 返回结果集
- 关闭连接(可能会关闭相关资源,即它可能会关闭
PreparedStatement
和与当前Connection
关联的ResultSet
),因为,如前面的链接中所述,finally
块始终至少执行JVM崩溃或您手动完成使用System.exit
应用程序。 - 使用关闭的
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应用程序)中工作,则不应使用静态方法来处理数据库操作。
这真的有帮助。