2

次のコード スニペットでは、

1) try-catch ブロックは、(AutoClose によって)「conn.close()」を呼び出す前に「conn.rollback()」を自動的に呼び出しますか? そうでない場合、finally { conn.rollback(); }そのブロックに を追加する必要がありますか?

2) Connection オブジェクトが bar() メソッドに渡される方法と、その中の try-catch メソッドは正しいですか?

public void foo() {
        try (Connection conn = datasource.getConnection()) {

            bar(conn, "arg");
            conn.commit();

        } catch (SQLException e) {
            e.printStackTrace();
        }

    }

    public void bar(Connection conn, String args) throws SQLException {
        try (PreparedStatement ps = conn.prepareStatement("SOME_QUERY")) {
            // Do something
            ps.executeUpdate();
        } catch (SQLException err) {
            throw err;
        }
    }
4

1 に答える 1

7

try-with-resourcesは、でclose()メソッドを呼び出すだけConnectionです。Connection.close()トランザクションがアクティブなときに呼び出すことの効果は、実装によって定義されます。

メソッドを呼び出す前に、アクティブなトランザクションをアプリケーションで明示的にコミットまたはロールバックすることを強くお勧めcloseします。closeメソッドが呼び出され、アクティブなトランザクションがある場合、結果は実装定義です。

言い換えれば、それに依存せず、明示的にcommit()orrollback()を呼び出してください。実際の動作はドライバー間で、おそらく同じドライバーのバージョン間でも異なるためです。

あなたの例を考えると、私は提案します:

public void foo() {
    try (Connection conn = datasource.getConnection()) {
        bar(conn, "arg");
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

public void bar(Connection conn, String args) throws SQLException {
    try (PreparedStatement ps = conn.prepareStatement("SOME_QUERY")) {
        // Do something
        ps.executeUpdate();
        conn.commit();
    } catch (SQLException err) {
        conn.rollback();
        throw err;
    }
}

connそれを作成した のcatchまたはfinallyブロックでは使用できないため、tryネストすることもできます。

public void foo() {
    try (Connection conn = datasource.getConnection()) {
        try {
            bar(conn, "arg");
            conn.commit();
        } catch (Exception ex) {
            conn.rollback();
            throw ex;
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
}
于 2013-03-28T15:09:43.640 に答える