Вопрос-ответ

Closing database connections in Java

Закрытие подключений к базе данных в Java

Я немного запутался. Я читал ниже из Java Database Connectivity:

Connection conn = DriverManager.getConnection(
"jdbc:somejdbcvendor:other data needed by some jdbc vendor",
"myLogin",
"myPassword" );

Statement stmt = conn.createStatement();
try {
stmt.executeUpdate( "INSERT INTO MyTable( name ) VALUES ( 'my name' ) " );
} finally {
// It's important to close the statement when you are done with it
stmt.close();
}

Вам не нужно закрывать conn соединение?
Что на самом деле происходит, если conn.close() не выполняется?

У меня есть частное веб-приложение, которое я поддерживаю, которое в настоящее время не закрывает ни одну из форм, но действительно ли важна stmt одна, conn one или обе?

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

Переведено автоматически
Ответ 1

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

На самом деле, безопасный шаблон в Java заключается в закрытии ваших ResultSet, Statement и Connection (в таком порядке) в finally блоке, когда вы закончите с ними. Что-то вроде этого:

Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;

try {
// Do stuff
...

} catch (SQLException ex) {
// Exception handling stuff
...
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) { /* Ignored */}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) { /* Ignored */}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) { /* Ignored */}
}
}

finally Блок может быть немного улучшен (чтобы избежать проверки null):

} finally {
try { rs.close(); } catch (Exception e) { /* Ignored */ }
try { ps.close(); } catch (Exception e) { /* Ignored */ }
try { conn.close(); } catch (Exception e) { /* Ignored */ }
}

Но, тем не менее, это чрезвычайно подробно, поэтому в конечном итоге вы обычно используете вспомогательный класс для закрытия объектов в безопасных для null вспомогательных методах, и finally блок становится чем-то вроде этого:

} finally {
DbUtils.closeQuietly(rs);
DbUtils.closeQuietly(ps);
DbUtils.closeQuietly(conn);
}

И, на самом деле, в Apache Commons DBUtils есть DbUtils класс, который именно это и делает, поэтому нет необходимости писать свой собственный.

Ответ 2

Всегда лучше закрывать объекты базы данных / ресурсов после использования. Лучше закрыть объекты connection, resultset и statement в finally блоке.

До появления Java 7 все эти ресурсы необходимо было закрывать с помощью finally блока. Если вы используете Java 7, то для закрытия ресурсов вы можете поступить следующим образом.

try(Connection con = getConnection(url, username, password, "org.postgresql.Driver");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sql);
) {

// Statements
}
catch(....){}

Теперь объекты con, stmt и rs становятся частью блока try, и Java автоматически закрывает эти ресурсы после использования.

Ответ 3

На самом деле, лучше всего, если вы используете блок try-with-resources, и Java закроет для вас все подключения при выходе из блока try.

Вы должны сделать это с любым объектом, который реализует AutoClosable.

try (Connection connection = getDatabaseConnection(); Statement statement = connection.createStatement()) {
String sqlToExecute = "SELECT * FROM persons";
try (ResultSet resultSet = statement.execute(sqlToExecute)) {
if (resultSet.next()) {
System.out.println(resultSet.getString("name");
}
}
} catch (SQLException e) {
System.out.println("Failed to select persons.");
}

Вызов getDatabaseConnection только что создан. Замените его вызовом, который получает соединение JDBC SQL или соединение из пула.

Ответ 4

Достаточно закрыть просто Statement и Connection. Нет необходимости явно закрывать ResultSet объект.

В документации Java говорится о java.sql.ResultSet:


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



Спасибо BalusC за комментарии: "Я бы не стал на это полагаться. Некоторые драйверы JDBC отказывают в этом".

java