Изпълнение на JDBC заявка

Изправен съм пред проблем, докато изпълнявам заявки. Използвам един и същи resultSet и оператор за изпълнение на всички заявки. Сега се сблъсквам с периодично SQlException, което казва, че връзката вече е затворена. Сега трябва или да имаме отделен resultSet за всяка заявка, или да имаме заключване като структура. Може ли някой да каже кое е по-добро. Мисля, че въвеждането на ключалки ще забави процеса. Прав ли съм?

Актуализация: За да бъдем по-ясни. Грешката може да възникне, защото блокът 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(Un известен източник) на 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 
} 

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