在以下代码段中,
1)在调用“conn.close()”(通过AutoClose)之前,try-catch块是否会自动调用“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;
}
}
答案 0 :(得分: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;
}
}
由于您无法在创建它的conn
或catch
块中使用finally
,因此您也可以嵌套它:
try