JDBC 查询执行
Posted
技术标签:
【中文标题】JDBC 查询执行【英文标题】:JDBC Query excecution 【发布时间】:2009-08-24 10:43:38 【问题描述】:我在执行查询时遇到问题。我使用相同的结果集和语句来执行所有查询。现在我遇到一个间歇性 SQlException 说连接已经关闭。现在我们必须为每个查询有单独的结果集或有类似锁的结构。谁能告诉我哪个更好。我认为引入锁会减慢这个过程。我说的对吗?
更新: 更清楚一点。错误可能是因为 finally 块在所有查询执行之前被调用并且连接被关闭并且将引发异常。
这是我得到的例外
java.sql.SQLException: 连接有 已经关闭。在 weblogic.jdbc.wrapper.PoolConnection.checkConnection(PoolConnection.java:81) 在 weblogic.jdbc.wrapper.ResultSet.preInvocationHandler(ResultSet.java:68) 在 weblogic.jdbc.wrapper.ResultSet_com_informix_jdbc_IfxResultSet.next(未知 来源)在 com.test.test.execute(test.java:76) 在 org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:413) 在 org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:225) 在 org.apache.struts.action.ActionServlet.process(ActionServlet.java:1858) 在 org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:459) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:760) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:853) 在 weblogic.servlet.internal.ServletStubImpl$ServletInvocationAction.run(ServletStubImpl.java:1077) 在 weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:465) 在 weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:348) 在 weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:7047) 在 weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321) 在 weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121) 在 weblogic.servlet.internal.WebAppServletContext.invokeServlet(WebAppServletContext.java:3902) 在 weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestImpl.java:2773) 在 weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:224) 在 weblogic.kernel.ExecuteThread.run(ExecuteThread.java:183)
示例代码:
ResultSet rst=null;
Statement stmt=null;
Connection con=DBConnection.getConnection();
stmt=con.createStatement();
rst=stmt.executeQuery("select * from dual");
while(rst.next())
: ://Some code
rst=stmt.executeQuery("select * from doctor where degree="BM");
while(rst.next())
//blah blah
finally
//close con,rst and stmt
【问题讨论】:
问题很可能出在您没有向我们展示的代码中。 【参考方案1】:您没有重复使用结果集,而是泄漏了结果集。 rst=stmt.executeQuery... 生成一个新的结果集,之前的结果集永远不会关闭:(
【讨论】:
【参考方案2】:似乎有问题的代码在多线程环境中存在问题。
DBConnection.getConnection() 可能正在向所有线程返回相同的连接。当多个线程同时处理多个请求时,第一个完成该方法执行的线程将关闭连接,让所有其他线程高高在上。
我在这里推测,但似乎 DBConnection 返回的连接对象是 DBConnection 对象的实例成员,这对于多线程环境中的连接管理器来说是一种不好的做法。
代码修复将避免使用 Connection、Statement(等)和 ResultSet 对象的实例成员。
【讨论】:
【参考方案3】:如果不了解您的代码,我不确定发生了什么。有螺纹吗?底层数据库是否出现故障(或者您是否正在失去与它的连接)。
我要做的一件事是实现连接池(比如通过Apache DBCP)。该框架将维护一个与您的数据库的连接池,并在将这些连接分发给您之前验证这些连接。每次进行查询(或可能是一组查询)时,您都会要求建立新的连接,但因为它们是共用的,所以这不应该是一个主要的开销。
【讨论】:
不,它不是线程化的。我使用的是单个连接、结果集和语句。我对每个查询都使用相同的语句和结果集 如何使用相同的结果集?您的意思是您对每个查询都使用相同的代码并每次都实例化一个新的结果集?我认为一个例子会很好。【参考方案4】:除非你与数据库的连接真的关闭了,否则我认为你做了更多这样的事情:
try
return resultSet.getBoolean("SUCCESS");
finally
resultSet.close();
此代码实际上会在评估结果集之前关闭连接,从而导致您显示异常。
【讨论】:
不,这不可能。 finally 子句确实在方法返回之前执行,但不是在 return 语句被评估之前执行。以上是关于JDBC 查询执行的主要内容,如果未能解决你的问题,请参考以下文章
使用 JDBC 驱动程序执行 Sql 查询时出现 NetworkOnMainThreadException