什么时候应该调用connection.rollback()方法?

Rak*_*yal 3 java database jdbc

请告诉我们何时需要调用connection.rollback()方法;

try{
  connection = getConnection();
  connection.setAutoCommit(false);
  pstmt1 = connection.preparedstatement ( ... );
  ...
  pstt1.executeUpdate();
  pstmt2 = connection.preparedstatement ( ... );
  ...
  pstt2.executeUpdate();
  connection.commit();
}catch ( Exception sqe ) {  sqe.printStacktrace();
}finally {
  closeQuitely ( pstmt1 );
  closeQuitely ( pstmt2 );
  closeQuitely ( connection );
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中我们没有使用connection.rollback(),但是如果发生了一些异常,即使这样一切都会正常工作[我猜],cos连接已经在autoCommit = false模式下设置了.

那么当我们需要使用这种方法时可能出现的情况.请发布示例.

djn*_*jna 5

在特殊情况下,您的交易未解决。最终它会超时,正如你所说,它会回滚。但在此之前(可能需要几分钟)您的事务所占用的所有锁都将被保留。连接无法意识到您可能不只是要 commit()。像这样长时间持有锁对于并发来说非常有利。

将回滚添加到您的异常情况中。

关闭连接可能也会终止事务。然而,当使用简单的 JDBC 时,如果存在应用程序服务器中实现的连接池,则关闭连接具有“返回池”的语义,并且连接池将保留连接与当前事务的关联。如果稍后在您的代码中,仍在同一事务的范围内,您请求连接,池将返回相同连接。这对于编写模块化应用程序来说确实非常方便,但缺点是您不能假设关闭连接可以解决事务。

begin tran

// call a method
    get connection

    work

    close connection

// call another method

    get connection  // you get the **same** connection still associated with the tran

    work

    close connection

commit
Run Code Online (Sandbox Code Playgroud)


Adr*_*onk 5

当您关闭连接时,您的交易将被终止.大多数DBMS会回滚你的交易,因为他们不知道在什么情况下连接被终止(可能你的程序被杀了?).因此,如果您已经提交,则回滚将不执行任何操作.

另一方面,如果您正在使用Connection-Pooling,当您关闭连接时,Pool Manager会拦截它,并且可能(希望)回滚连接并保持连接打开.

在catch子句内部甚至在finally子句中回滚是一种很好的做法.提交后执行不必要的回滚通常没有坏处.

顺便说一句,如果您使用Postgres,在开始确保重置事务开始时间之前回滚是个好主意.这是因为Postgres将current_timestamp值保存到事务开始的时间,如果你使用池化连接,这可能是很久以前的事了!