Страницы

Поиск по вопросам

воскресенье, 5 января 2020 г.

Обязательно ли закрывать Statement и ResultSet?

#servlet #jdbc #java


Java сервлет при каждом вызове получает Connection с SQL базой данных (Oracle oracle.jdbc.driver.OracleDriver,
используя DriverManager.getConnection()), затем создает Statement и ResultSet. Все
в локальных переменных. Очевидно (везде пишут об этом), что Statement и ResultSet надо
закрывать.
Вопрос: будет ли утечка ресурсов, если не закрыть ResultSet или Statement?
UPD (в ответ на ответы).
Итак, Oracle XE development, соответственно, версия бесплатная, ограниченная (но
настолько!)
Прежде всего, Statement и ResultSet в нормальном режиме я закрывал, а вот для Exception(s)
ограничился только закрытием Connection в try { ... } finally { ... }
Поэтому для тестирования сначала выбросил Statement и ResultSet close() и в непрерывном
цикле на 77 connection все свалилось, но свалилось по причине ORA-12519. Не Могу ОТКРЫТЬ
новую connection!!! Вот те раз, я же их закрываю! Вернул все close() - то же самое.
Я ведь в непрерывном цикле запросы не гонял, предположить такую подлянку не мог!
Пробую цикл с одним соединением (при закрытии Statement и ResultSet) все работает
(1000000 циклов). Если не закрывать, сначала падает по ResultSet, потом по Statement. 
Почитал про ORA-12519 в сети, увеличил ресурсы (alter system set processes=150 scope=spfile;,
это кому-то помогло) падение отодвинулось до 230 соединений и все.
Потом вычитал, оказалось, дело в том, что ограничено количество соединений в единицу
времени. Сделал 100 в секунду - то идет, то валится. Сейчас идет с 50 в секунду (цикл
100000 после каждой сотни открытых-закрытых sleep(2000)) - YES - прошло. 
Так что, спасибо всем!!!
UPD-2
Искал оптимальную задержку (при повторе попытки открыть новое соединение) оказалось
350 миллисекунд - для 1000 циклов у меня общая задержка в худшем случае 6.3 с. Почему-то
она плавает, нет повторяемости. Для других задержек (от 50мс до 3с) общее время хуже.
Нет ли у кого идей, как правильно организовать подобные замеры?
UPD-3
Oracle - это загадка. Попробовал на работе с "боевой" 11.g Enterprise Edition на сервере.
Выполняется раз в 10 медленнее, поэтому гонял до 10000 циклов. Нет сбоев! Без разницы,
закрываю Statement и ResultSet или нет. Работает и все тут (без всяких sleep()), хотя
драйвер в программе тот же самый от XE Development.
У кого-нибудь есть идеи???  Как вообще правильно программировать взаимодействие с
базой?    


Ответы

Ответ 1



Насчет statement не уверен, но точно знаю, что с resultset будет. Кажется, предел находится на 32к незакрытых resultset, oracle не сможет возвращать результаты выборки. имхо, лучше всегда за собой убирать :)

Ответ 2



Спецификация JDBC рекомендует всегда все закрывать вручную. Однако при этом утверждается, что all Statement objects will be closed when the connection that created them is closed и что closing a Statement object will close and invalidate any instances of ResultSet produced by that Statement object т.е. закрытие соединения должно закрыть все порожденные объекты иерархически. Однако авторы, видимо, решили перестраховаться и защитить вас от случаев, когда "должно" в реализации драйвера перетекает в "мы постараемся" - по техническим причинам либо из-за невнимательности. Видимо, специкация спецификацией, а на практике "всякое может быть" (как бы быдлокодно это не звучало) - так что лучше закрывать самостоятельно. Лично ине кажется, что в драйвере Оракла тут все же будет ОК и с автоматическим закрытием, а вот при переходе на другую БД могут быть сюрпризы.

Комментариев нет:

Отправить комментарий