JDBC 查询执行

发布于 2024-08-02 15:35:04 字数 2337 浏览 2 评论 0原文

我在执行查询时遇到问题。我使用相同的结果集和语句来执行所有查询。现在我面临间歇性的 SQlException,表示连接已关闭。现在我们必须为每个查询拥有单独的结果集,或者具有像这样的锁结构。谁能告诉我哪个更好。我认为引入锁会减慢进程。我是对的吗?

更新: 更清楚地说,可能会发生错误,因为在所有查询执行之前调用了finally块,并且连接关闭并抛出异常。

这是我得到的例外

java.sql.SQLException:连接已 已经被关闭了。在 weblogic.jdbc.wrapper.PoolConnection.checkConnection(PoolConnection.java:81) 在 weblogic.jdbc.wrapper.ResultSet.preIncationHandler(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$ServletInitationAction.run(ServletStubImpl.java:1077) 在 weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:465) 在 weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:348) 在 weblogic.servlet.internal.WebAppServletContext$ServletInitationAction.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 
} 

I am facing an issue while executing queries.I use the same resultSet and statement for excecuting all the queries.Now I face an intermittent SQlException saying that connection is already closed.Now we have to either have separate resultSet for each query or have lock like structure.Can anyone tell which is better.I think introducing locks will slow down the process.Am I right?

Update:
To be more clear.The error may happen because the finally block gets called before all the queries get executed and the connection gets closed and exception will be thrown.

This is the exception I get

java.sql.SQLException: Connection has
already been closed. at
weblogic.jdbc.wrapper.PoolConnection.checkConnection(PoolConnection.java:81)
at
weblogic.jdbc.wrapper.ResultSet.preInvocationHandler(ResultSet.java:68)
at
weblogic.jdbc.wrapper.ResultSet_com_informix_jdbc_IfxResultSet.next(Unknown
Source) at
com.test.test.execute(test.java:76)
at
org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:413)
at
org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:225)
at
org.apache.struts.action.ActionServlet.process(ActionServlet.java:1858)
at
org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:459)
at
javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
at
javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at
weblogic.servlet.internal.ServletStubImpl$ServletInvocationAction.run(ServletStubImpl.java:1077)
at
weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:465)
at
weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:348)
at
weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:7047)
at
weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at
weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)
at
weblogic.servlet.internal.WebAppServletContext.invokeServlet(WebAppServletContext.java:3902)
at
weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestImpl.java:2773)
at
weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:224)
at
weblogic.kernel.ExecuteThread.run(ExecuteThread.java:183)

Sample code:

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 
} 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

乱了心跳 2024-08-09 15:35:04

您没有重用结果集,而是泄漏了结果集。
rst=stmt.executeQuery... 生成一个新的结果集,并且以前的结果集永远不会关闭:(

you are not reusing the resultset, you are leaking resultsets.
rst=stmt.executeQuery... generates a new resultset and the previous resultset is never closed :(

瑾兮 2024-08-09 15:35:04

看来有问题的代码在多线程环境中存在问题。

DBConnection.getConnection() 可能会向所有线程返回相同的连接。当多个线程处理多个请求时,第一个完成该方法执行的线程将关闭连接,使所有其他线程处于高位和杂项状态。

我在这里推测,但 DBConnection 返回的连接对象似乎是 DBConnection 对象的实例成员,这对于多线程环境中的连接管理器来说是一种不好的做法。

代码修复将避免使用 Connection、Statement(等等)和 ResultSet 对象的实例成员。

It appears that the code in question has issues in multi-threaded environment.

DBConnection.getConnection() is probably returning the same connection to all threads. When multiple threads are processing multiple requests, the first thread that finishes execution of the method will close the connection, leaving all other threads high and sundry.

I'm speculating here, but is appears that the connection object returned by DBConnection is an instance member of the DBConnection object, and that would qualify as a bad practice for a connection manager in a multi-threaded environment.

A code fix would avoid the usage of instance members for Connection, Statement (and the like), and the ResultSet objects.

夏见 2024-08-09 15:35:04

如果不了解更多有关您的代码的信息,我不确定发生了什么。是有螺纹的吗?底层数据库是否出现故障(或者您是否失去了与它的连接)。

我要做的一件事是实现连接池(例如,通过 Apache DBCP)。该框架将维护一个与数据库的连接池,并在将这些连接分发给您之前验证。每次进行查询(或者可能是一组查询)时,您都会要求一个新连接,但因为它们是池化的,所以这不应该是一个主要的开销。

I'm not sure what's going on without knowing more about your code. Is it threaded ? Is the underlying database going down (or are you losing connectivity to it).

One thing I would do is to implement connection pooling (via Apache DBCP, say). This framework will maintain a pool of connections to your database and validate these connections before handing them out to you. You would ask for a new connection each time you make a query (or perhaps set of queries) but because they're pooled this shouldn't be a major oeverhead.

平定天下 2024-08-09 15:35:04

除非您与数据库的连接确实已关闭,否则我认为您做了更像这样的事情:

try {
    return resultSet.getBoolean("SUCCESS");
} finally {
    resultSet.close();
}

此代码实际上会在评估结果集之前关闭连接,从而导致您显示的异常。

Unless your connection to the database has really been closed I think you did something more like this:

try {
    return resultSet.getBoolean("SUCCESS");
} finally {
    resultSet.close();
}

This code will actually close the connection before your result set is being evaluated, resulting in the exception you show.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文