在jdbc中执行事务时调用conn.rollback是多余的?

时间:2014-09-06 11:06:54

标签: jdbc transactions

虽然已经多次询问过这个特殊问题,但我仍然不确定。我的设置是这样的:我使用jdbc并将autocommit视为false。假设我有3个插入语句,我想作为事务执行,后跟conn.commit()

示例代码:

try {
    getConnection()
    conn.setAutoCommit(false);
    insertStatment() //#1
    insertStatment() //#2
    insertStatment() //#3, could throw an error
    conn.commit()
} catch(Sql exception) {
    conn.rollback() // why is it needed?
}

说我有两个场景

  1. 要么,不会有任何错误,我们会致电conn.commit(),所有内容都会更新。
  2. 说前两个语句工作正常,但第三个语句有错误。因此,conn.commit()未被调用,我们的数据库处于一致状态。那么为什么我需要拨打conn.rollback()
  3. 我注意到有人提到回滚会对连接池产生影响吗?任何人都可以向我解释它会如何影响?

1 个答案:

答案 0 :(得分:1)

仍然需要rollback()。不提交或回滚事务可能会在数据库中保留资源(事务处理,日志或记录版本等)。明确提交或回滚可确保释放这些资源。

当您继续使用连接然后提交时,不执行显式回滚也可能会产生不良影响。在事务中成功完成的更改(示例中为#1和#2)将保持不变。

Connection apidoc但是确实说“如果已禁用自动提交模式,则必须显式调用方法提交以提交更改;否则,将不保存数据库更改。”应解释为:a Connection.close()导致回滚。但是我相信有一些JDBC驱动程序实现用于提交连接关闭。

正确实施不应存在对连接池的影响。关闭从连接池获取的逻辑连接应该与关闭物理连接具有相同的效果:应回滚打开的事务。但是,由于性能原因,有时连接池未正确实现或出现错误或缺少快捷方式,所有这些都可能导致在您从池中获得逻辑连接时已经启动了打开的事务。

因此:明确地调用回滚。