Выполнение запросов JDBC

Я столкнулся с проблемой при выполнении запросов. Я использую один и тот же набор результатов и оператор для исключения всех запросов. Теперь я сталкиваюсь с прерывистым 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_java_com_informance (неизвестный) .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 (ServletStub10Implava). internal.ServletStubImpl.invokeServlet (ServletStubImpl.java:465) в webl ogic.servlet.internal.ServletStubImpl.invokeServlet (ServletStubImpl.java:348) по адресу weblogic.servlet.internal.WebAppServletContext $ ServletInvocationAction.run (WebAppServletContext.java:7047) по адресу weblogic.Ashentication.Authentication.Authentication.Authentication.AuthenticationServletContext. java: 321) в weblogic.security.service.SecurityManager.runAs (SecurityManager.java:121) в weblogic.servlet.internal.WebAppServletContext.invokeServlet (WebAppServletContext.java:3902) в weblogic.servletcrequute.inestplast. .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 
} 

person Community    schedule 24.08.2009    source источник
comment
Скорее всего, проблема где-то в коде, который вы нам не показываете.   -  person waxwing    schedule 24.08.2009


Ответы (4)


вы не используете повторно набор результатов, вы теряете наборы результатов. rst = stmt.executeQuery ... генерирует новый набор результатов, а предыдущий набор результатов никогда не закрывается :(

person Community    schedule 24.08.2009

Похоже, что рассматриваемый код имеет проблемы в многопоточной среде.

DBConnection.getConnection (), вероятно, возвращает одно и то же соединение для всех потоков. Когда несколько потоков обрабатывают несколько запросов, первый поток, который завершает выполнение метода, закроет соединение, оставив все остальные потоки на высоком уровне.

Я предполагаю здесь, но похоже, что объект соединения, возвращаемый DBConnection, является членом экземпляра объекта DBConnection, и это будет считаться плохой практикой для диспетчера соединений в многопоточной среде.

Исправление кода позволит избежать использования членов экземпляра для объектов Connection, Statement (и т.п.) и ResultSet.

person Vineet Reynolds    schedule 24.08.2009

Я не уверен, что происходит, не зная больше о вашем коде. Он резьбовой? Базовая база данных выходит из строя (или вы теряете подключение к ней).

Одна вещь, которую я бы сделал, - это реализовать пул соединений (скажем, через Apache DBCP). Эта структура будет поддерживать пул подключений к вашей базе данных и проверять эти подключения перед их передачей вам. Вы будете запрашивать новое соединение каждый раз, когда делаете запрос (или, возможно, набор запросов), но поскольку они объединены в пул, это не должно быть серьезной проблемой.

person Brian Agnew    schedule 24.08.2009
comment
Нет, это не потоки. Я использую одно соединение, набор результатов и оператор. Я использую один и тот же оператор и набор результатов для каждого запроса. - person ; 24.08.2009
comment
Как можно использовать тот же набор результатов? Вы имеете в виду, что вы используете один и тот же код для каждого запроса и каждый раз создаете новый набор результатов? Я думаю, что пример был бы неплохим. - person Brian Agnew; 24.08.2009

Если ваше соединение с базой данных действительно не было закрыто, я думаю, вы сделали что-то вроде этого:

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

Этот код фактически закроет соединение до того, как ваш набор результатов будет оценен, что приведет к отображаемому вами исключению.

person Bombe    schedule 24.08.2009
comment
Нет, этого не может быть. Предложение finally действительно выполняется до возврата из метода, но не до того, как оператор return будет оценен. - person waxwing; 24.08.2009