Try / Try-with-resources и закрытие Connection, Statement и ResultSet

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

public void doQueries() throws MyException{
    Connection con = null;
    try {
        con = DriverManager.getConnection(dataSource);
        PreparedStatement s1 = con.prepareStatement(updateSqlQuery);
        PreparedStatement s2 = con.prepareStatement(selectSqlQuery);

        // Set the parameters of the PreparedStatements and maybe do other things

        s1.executeUpdate();
        ResultSet rs = s2.executeQuery();

        rs.close();
        s2.close();
        s1.close();
    } catch (SQLException e) {
        throw new MyException(e);
    } finally {
        try {
            if (con != null) {
                con.close();
            }
        } catch (SQLException e2) {
            // Can't really do anything
        }
    }
}

Мне не нравится этот подход, и у меня есть два вопроса об этом:

1.A) Я думаю, что, если какое-либо исключение выдается, когда мы делаем «другие вещи», или в строкеrs.close() или жеs2.close() затемs1 не был бы закрыт, когда метод заканчивается. Я прав насчет этого?

1.B) Профессор продолжает просить меня явно закрыть ResultSet (даже когда документация Statement ясно дает понять, что он закроет ResultSet). Она говорит, что Sun рекомендует это. Есть ли причина для этого?

Теперь это то, что я считаю правильным кодом для того же:

public void doQueries() throws MyException{
    Connection con = null;
    PreparedStatement s1 = null;
    PreparedStatement s2 = null;
    try {
        con = DriverManager.getConnection(dataSource);
        s1 = con.prepareStatement(updateSqlQuery);
        s2 = con.prepareStatement(selectSqlQuery);

        // Set the parameters of the PreparedStatements and maybe do other things

        s1.executeUpdate();
        ResultSet rs = s2.executeQuery();

    } catch (SQLException e) {
        throw new MyException(e);
    } finally {
        try {
            if (s2 != null) {
                s2.close();
            }
        } catch (SQLException e3) {
            // Can't do nothing
        }
        try {
            if (s1 != null) {
                s1.close();
            }
        } catch (SQLException e3) {
            // Can't do nothing
        }
        try {
            if (con != null) {
                con.close();
            }
        } catch (SQLException e2) {
            // Can't do nothing
        }
    }
}

2.А) Является ли этот код правильным? (Гарантируется ли, что все будет закрыто после завершения метода?)

2.B) Это очень большой и многословный (и становится еще хуже, если есть больше утверждений) Есть ли более короткий или более элегантный способ сделать это без использования try-with-resources?

Наконец, этот код мне нравится больше всего

public void doQueries() throws MyException{
    try (Connection con = DriverManager.getConnection(dataSource);
         PreparedStatement s1 = con.prepareStatement(updateSqlQuery);
         PreparedStatement s2 = con.prepareStatement(selectSqlQuery))
    {

        // Set the parameters of the PreparedStatements and maybe do other things

        s1.executeUpdate();
        ResultSet rs = s2.executeQuery();

    } catch (SQLException e) {
        throw new MyException(e);
    }
}

3) Является ли этот код правильным? Я думаю, что моему профессору не нравится этот способ, потому что нет явного закрытия ResultSet, но она сказала мне, что она в порядке с этим, пока в документации ясно, что все закрыто. Можете ли вы дать какую-либо ссылку на официальную документацию с похожим примером или на основании документации показать, что нет проблем с этим кодом?

Ответы на вопрос(5)

Ваш ответ на вопрос