我有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
我做得不对?
答案 0 :(得分:8)
您将返回ResultSet
以供将来使用,但在使用它之后您将关闭连接,因此您无法检索数据,因为资源已关闭。请注意,即使您在finally
或try
代码块中返回某些内容,也始终会调用catch
,请参阅Does finally always execute in Java?
详细地说,这就是问题所在:
PreparedStatement
关联的ResultSet
和Connection
),因为如之前的链接中所述,{ {1}}阻止始终至少执行JVM崩溃或您使用finally
手动完成应用程序。System.exit
。它由于上一步而关闭。一种可能的解决方案是,您的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
}