#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 т.е. закрытие соединения должно закрыть все порожденные объекты иерархически. Однако авторы, видимо, решили перестраховаться и защитить вас от случаев, когда "должно" в реализации драйвера перетекает в "мы постараемся" - по техническим причинам либо из-за невнимательности. Видимо, специкация спецификацией, а на практике "всякое может быть" (как бы быдлокодно это не звучало) - так что лучше закрывать самостоятельно. Лично ине кажется, что в драйвере Оракла тут все же будет ОК и с автоматическим закрытием, а вот при переходе на другую БД могут быть сюрпризы.
Комментариев нет:
Отправить комментарий