如果java.sql.Connection#commit()抛出异常,是否需要回滚?

时间:2010-09-24 20:56:59

标签: java jdbc connection rollback

根据JAVA documentationConnection#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()调用包装到另一个方法中,该方法忽略了它抛出的任何异常,所以我想我没关系。我只是想知道这是否是处理事情的最佳方式。

4 个答案:

答案 0 :(得分:18)

根据Java 1.6 JDBC docs

,即使提交失败,回滚也很重要
  

强烈建议应用程序显式提交或   在调用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?