Закрытие соединений с базами данных на Java


Я немного запутался, я читал ниже от http://en.wikipedia.org/wiki/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? Что на самом деле происходит, если соед.close () не происходит?

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

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

6 93

6 ответов:

когда вы закончите с использованием вашего 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 */}
    }
}

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

} 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 класс, который именно это делает, поэтому нет необходимости писать свой собственный.

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

до Java7, все эти ресурсы должны быть закрыты с помощью 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 автоматически закрывает эти ресурсы после использовать.

надеюсь, что я был полезен.

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

да. Вам нужно закрыть результирующий набор, оператор и соединение. Если соединение пришло из пула, закрытие его фактически отправляет его обратно в пул для повторного использования.

обычно вы должны сделать это в finally{} блок, такой, что если возникает исключение, вы все равно получаете шанс закрыть это.

многие фреймворки будут следить за этой проблемой выделения/освобождения ресурсов для вас. например, Весна JdbcTemplate. Apache DbUtils имеет методы, чтобы смотреть после закрытия resultset / statement / connection ли null или нет (и ловить исключения при закрытии), которые также могут помочь.

да, вам нужно закрыть соединение. В противном случае клиент базы данных обычно сохраняет соединение сокета и другие ресурсы открытыми.

на самом деле, лучше всего, если вы используете блок 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 или соединение из пула.