繁体   English   中英

con.rollback() 会通过 con.commit() 回滚已经提交的更改吗?

[英]Will con.rollback() rollback already commited changes by con.commit()?

我现在正在处理 Legacy 项目,它需要在某些地方对低级 JDBC API 有深入的了解,我看到这样的代码:

try {
    con = ....
    con.setAutoCommit(false);
    //insert_1 pack to db
    con.commit();
    //insert_2 pack to db
    con.commit();
    //insert_3 pack to db
    con.commit();
} catch (SQLException e) {
    try {
        con.rollback();
    } catch (SQLException e) {
        log.warn("SQLException on rolling back the destination connection. ", e);
            throw e;
        }
    throw ex;
}

有时 con.rollback(); 未在 catch 中调用:

try {
        con = ....
        con.setAutoCommit(false);
        //insert_1 pack to db
        con.commit();
        //insert_2 pack to db
        con.commit();
        //insert_3 pack to db
        con.commit();
    } catch (SQLException e) {      
        throw new MyBusinessException(ex);
    }

你能从交易的角度解释一下区别吗?

PS我已经阅读了用于回滚的 java 文档,但它没有回答我的问题。

撤消在当前事务中所做的所有更改并释放此 Connection 对象当前持有的所有数据库锁。 仅当禁用自动提交模式时才应使用此方法。 抛出: SQLException - 如果发生数据库访问错误,在参与分布式事务时调用此方法,在关闭的连接上调用此方法或此 Connection 对象处于自动提交模式另请参见:setAutoCommit

代码看起来不正确。

  1. 执行了多个提交。 这意味着显式回滚只会将状态回滚到上次提交的开头。 我想这不是回滚应该做的。

  2. 如果没有调用显式回滚,至少在池数据库连接中(在池数据库连接中,连接永远不会关闭,而是重用)已经执行的语句仍在事务中。 即在这里调用rollback稍后会导致奇怪的错误,并且还会回滚实际上与当前业务流程无关的最后执行的语句。

  3. 我看不到close

对于您的问题,这意味着第二个代码片段应该:

  1. 在单个非池连接中,在最后一次提交后不提交最后一条语句,这是正确的(偶然)。
  2. 在池连接中,让事务挂起,这可能会导致错误,即下一个提交某些内容并重用连接的业务逻辑也将提交此错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM