Говорят, что это хорошая привычка - закрывать все ресурсы JDBC после использования. Но если у меня есть следующий код, нужно ли закрывать Resultset и Statement?
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = // Retrieve connection
stmt = conn.prepareStatement(// Some SQL);
rs = stmt.executeQuery();
} catch(Exception e) {
// Error Handling
} finally {
try { if (rs != null) rs.close(); } catch (Exception e) {};
try { if (stmt != null) stmt.close(); } catch (Exception e) {};
try { if (conn != null) conn.close(); } catch (Exception e) {};
}
Вопрос в том, выполняет ли закрытие соединения работу или оставляет ли он некоторые ресурсы в использовании.
Ответы:
То, что вы сделали, является идеальной и очень хорошей практикой.
Причина, по которой я говорю, это хорошая практика ... Например, если по какой-то причине вы используете «примитивный» тип пула баз данных и вызываете
connection.close()
, соединение будет возвращено в пул, иResultSet
/Statement
никогда не будет закрыто, а затем вы столкнется с множеством разных новых проблем!Так что вы не всегда можете рассчитывать на
connection.close()
уборку.Надеюсь, это поможет :)
источник
Java 1.7 делает нашу жизнь намного проще благодаря выражению try-with-resources .
Этот синтаксис довольно короткий и элегантный. И
connection
действительно будет закрыт, даже когдаstatement
не может быть создан.источник
;
)Из Javadocs :
Тем не менее, Javadocs не очень ясно, закрываются ли
Statement
иResultSet
при закрытии базовогоConnection
. Они просто утверждают, что закрывают соединение:На мой взгляд, всегда явно близко
ResultSets
,Statements
иConnections
когда вы закончите с ними, реализацияclose
может варьироваться между драйверами базы данных.Вы можете сэкономить много лишнего кода, используя такие методы, как
closeQuietly
в DBUtils от Apache.источник
Я сейчас использую Oracle с Java. Вот моя точка зрения:
Вы должны закрыть
ResultSet
иStatement
явно, потому что у Oracle ранее были проблемы с сохранением курсоров открытыми даже после закрытия соединения. Если вы не закроетеResultSet
(курсор), он выдаст ошибку, как Превышено максимальное количество открытых курсоров .Я думаю, что вы можете столкнуться с той же проблемой с другими базами данных, которые вы используете.
Вот учебник Закрыть ResultSet, когда закончите :
источник
Если вы хотите более компактный код, я предлагаю использовать Apache Commons DbUtils . В таком случае:
источник
Правильный и безопасный метод для закрытия ресурсов, связанных с JDBC, это (взято из Как правильно закрыть ресурсы JDBC - каждый раз ):
источник
Неважно, если
Connection
это пул или нет. Даже соединение с бассейном должно быть очищено перед возвращением в бассейн.«Очистить» обычно означает закрытие наборов результатов и откат любых ожидающих транзакций, но не закрытие соединения. В противном случае объединение теряет смысл.
источник
Нет, вам не нужно ничего закрывать, НО соединение. Согласно спецификациям JDBC, закрытие любого более высокого объекта автоматически закроет более низкие объекты. Закрытие
Connection
закроет всеStatement
s, которые установило соединение. Закрытие любогоStatement
закроет всеResultSet
s, которые были созданы этимStatement
. Неважно, еслиConnection
это пул или нет. Даже соединение с бассейном должно быть очищено перед возвращением в бассейн.Конечно, у вас могут быть длинные вложенные циклы при
Connection
создании большого количества операторов, тогда закрытие их целесообразно. Я почти никогда не закрываюсьResultSet
, кажется чрезмерным при закрытииStatement
илиConnection
БУДУ их закрывать.источник
Я создал следующий метод для создания многоразового использования One Liner:
Я использую этот код в родительском классе, который унаследован для всех моих классов, отправляющих запросы к БД. Я могу использовать Oneliner для всех запросов, даже если у меня нет resultSet. Метод заботится о закрытии ResultSet, Statement, Connection в правильном порядке. Вот так выглядит мой наконец блок.
источник
Насколько я помню, в текущем JDBC Resultsets и операторы реализуют интерфейс AutoCloseable. Это означает, что они автоматически закрываются после уничтожения или выхода из области видимости.
источник
close
вызывается в конце оператора try-with-resources. См. Docs.oracle.com/javase/tutorial/essential/exceptions/… и docs.oracle.com/javase/8/docs/api/java/lang/AutoCloseable.html .Некоторые удобные функции:
источник
С формой Java 6, я думаю, лучше проверить, закрыто она или нет перед закрытием (например, если какой-либо пул соединений высвобождает соединение в другом потоке) - например, некоторая проблема с сетью - оператор и состояние набора результатов могут быть закрыты. (это случается не часто, но у меня была эта проблема с Oracle и DBCP). Мой шаблон для этого (в старом синтаксисе Java):
Теоретически он не идеален на 100%, потому что между проверкой состояния закрытия и самим закрытием остается мало места для изменения состояния. В худшем случае вы получите предупреждение в течение длительного времени. - но это меньше, чем возможность изменения состояния в долгосрочных запросах. Мы используем этот шаблон в работе с «средней» нагрузкой (150 одновременных пользователей), и у нас не было с ним проблем - поэтому никогда не видели это предупреждающее сообщение.
источник
isClosed()
тесты, потому что закрывать любой из них, который уже закрыт, нельзя. Что устраняет проблему окна синхронизации. Что также будет устранено путем создания переменныхConnection, Statement
, иResultSet
local.