根据JAVA documentation,Connection#commit()
可以投掷SQLException
。我的问题是在这种情况下是否仍应发布回滚。
例如:
Connection con = null;
try {
// assume this method returns an opened connection with setAutoCommit(false)
con = createConnection();
// do DB stuff
con.commit();
} catch (SQLException e) {
if (con != null) {
// what if con.commit() failed, is this still necessary,
// will it hurt anything?
con.rollback();
}
} finally {
if (con != null) {
con.close();
}
}
我实际上将con.rollback()调用包装到另一个方法中,该方法忽略了它抛出的任何异常,所以我想我没关系。我只是想知道这是否是处理事情的最佳方式。
答案 0 :(得分:18)
强烈建议应用程序显式提交或 在调用close方法之前回滚活动事务。如果 调用close方法并且有一个活动事务,即 结果是实现定义的。
这意味着如果您没有显式调用回滚,某些JDBC实现可能会在关闭连接之前调用commit。
回滚的另一个好理由是Xepoch建议,当使用连接池时,它更为重要。
从连接池获取连接时,大多数实现将在为您提供连接之前执行connection.setAutoCommit(defaultAutoCommit)
并根据JavaDocs:
如果在事务和自动提交模式期间调用此方法 已更改,事务已提交
如果connection.rollback()
引发异常 - 那么这是一个棘手的问题......
答案 1 :(得分:6)
我会为了清理目的而进行显式回滚。虽然db中的更改不会以任何方式保留,但显然让数据库知道你已经在这里完成了。就像你明确地关闭连接的方式一样,无需等待垃圾收集连接对象。
显然,这不是一个技术性答案,我也有兴趣了解这样做是否有实际意义。
答案 2 :(得分:4)
“返回一个打开的连接?”如果该连接在池中共享(并且可能在将来),则不希望另一个事务提交您的早期工作。我已经看到许多插入符合JDBC接口的池连接驱动程序的客户/解决方案案例,Connection.close()
也可用于将Connection返回池中。
此外,更好try{}catch{}
您的rollback()
(编辑,只读完整篇文章,但我总是想在回滚时记录异常)
答案 3 :(得分:1)
我这样做的常用方法是:
boolean bSuccess = false;
Connection con = null;
try {
// assume this method returns an opened connection with setAutoCommit(false)
con = createConnection();
// do DB stuff
bSuccess = true;
} catch (SQLException e)
{
}
finally
{
try
{
if (con != null)
{
if(bSuccess)
con.commit()
else
con.rollback();
con.close();
}
}
catch(SQLException sqle)
{
log("Log the error here");
// do nothing we tried
}
}
据说,如果查询有效,我从未见过提交或回滚失败 如果您有待处理的事务,则大多数数据库都有工具来释放它们。大多数应用服务器将继续重试提交和回滚,直到它们可以连接。
您可能希望查看此帖子:Is it necessary to write ROLLBACK if queries fail?