2

在以下代码片段中,

1) try-catch 块是否在调用“conn.close()”之前自动调用“conn.rollback()”(通过 AutoClose)?如果没有,我是否必须在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(),否则rollback()驱动程序之间的实际行为会有所不同,甚至可能在同一驱动程序的版本之间。

鉴于您的示例,我建议:

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;
    }
}

由于您不能在创建它conncatchorfinally块中使用,您也可以嵌套它: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 回答