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

时间:2022-11-15 20:03:03

Please let me know when do we require to call the method connection.rollback();

请告诉我们何时需要调用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 );
}

In above code we are not using connection.rollback(), but if some exception occurs, even then everything will work fine [ i guess ], cos connection is already set in autoCommit = false mode.

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

So what could be the possible situation when we need to use this method. Please post the example as well.

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

3 个解决方案

#1


5  

When you close your connection, your transaction will be terminated. Most DBMS's will rollback your transaction because they don't know under what circumstances the connection was terminated (maybe your program was killed?). So if you've already committed, the rollback will do nothing.

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

On the other hand, if you're using Connection-Pooling, when you close the connection, the Pool Manager intercepts it and will probably (hopefully) rollback the connection and leave the connection open.

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

It's good practice to rollback inside the catch clause, or even in the finally clause. It generally doesn't hurt to do an unnecessary rollback after a commit.

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

As an aside, if you're using Postgres, it's a good idea to rollback before you start to ensure that your transaction start-time is reset. That's because Postgres holds the current_timestamp value to the time the transaction started and if you're using pooled Connections, this could have been a long time ago!

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

#2


4  

In the exception case your transaction is unresolved. Eventually it will timeout, and as you say it will rollback. But until then (which may be several minutes) all the locks taken by your transaction will be held. The connection has no way to realise that you may not just about to commit(). Holding locks for an extended period like that is very back for concurrency.

在例外情况下,您的交易未得到解决。最终会超时,正如你所说它会回滚。但在此之前(可能是几分钟),您的交易所持有的所有锁都将被保留。连接无法意识到您可能不只是提交()。像这样长时间持有锁是非常适合并发的。

Add the rollback to your exception case.

将回滚添加到例外情况。

It may appear that closing your connection will also terminate the transction. When using simple JDBC, however in the presence of connection pooling as implemented in application servers closing the connection has the semantic of "return to pool" and the connection pool will retain the connection's association with your current transaction. If later in your code, still in the scope of the same transaction, you ask for a connection the pool will return you the same connection. This is very handy indeed for writing moular applications, but has the penalty that you cannot assume closing a connection resolves the transaction.

看来关闭连接也会终止转换。使用简单JDBC时,但是在应用程序服务器中实现的连接池存在时,关闭连接的语义为“返回池”,连接池将保留连接与当前事务的关联。如果稍后在您的代码中,仍然在同一事务的范围内,您要求连接,则池将返回相同的连接。这对于编写moular应用程序非常方便,但是你不能假设关闭连接来解决事务。

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

#3


0  

If you close a connection without committing then it will transaction will be rolled back. if you are using a connection pool, it is probably doing that for you.

如果在未提交的情况下关闭连接,则将回滚事务。如果您正在使用连接池,它可能正在为您执行此操作。

An explicit rollback is probably more appropriate when you encounter a condition that is not causing an exception but you still don't want to commit.

当您遇到不导致异常但仍然不想提交的条件时,显式回滚可能更合适。

#1


5  

When you close your connection, your transaction will be terminated. Most DBMS's will rollback your transaction because they don't know under what circumstances the connection was terminated (maybe your program was killed?). So if you've already committed, the rollback will do nothing.

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

On the other hand, if you're using Connection-Pooling, when you close the connection, the Pool Manager intercepts it and will probably (hopefully) rollback the connection and leave the connection open.

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

It's good practice to rollback inside the catch clause, or even in the finally clause. It generally doesn't hurt to do an unnecessary rollback after a commit.

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

As an aside, if you're using Postgres, it's a good idea to rollback before you start to ensure that your transaction start-time is reset. That's because Postgres holds the current_timestamp value to the time the transaction started and if you're using pooled Connections, this could have been a long time ago!

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

#2


4  

In the exception case your transaction is unresolved. Eventually it will timeout, and as you say it will rollback. But until then (which may be several minutes) all the locks taken by your transaction will be held. The connection has no way to realise that you may not just about to commit(). Holding locks for an extended period like that is very back for concurrency.

在例外情况下,您的交易未得到解决。最终会超时,正如你所说它会回滚。但在此之前(可能是几分钟),您的交易所持有的所有锁都将被保留。连接无法意识到您可能不只是提交()。像这样长时间持有锁是非常适合并发的。

Add the rollback to your exception case.

将回滚添加到例外情况。

It may appear that closing your connection will also terminate the transction. When using simple JDBC, however in the presence of connection pooling as implemented in application servers closing the connection has the semantic of "return to pool" and the connection pool will retain the connection's association with your current transaction. If later in your code, still in the scope of the same transaction, you ask for a connection the pool will return you the same connection. This is very handy indeed for writing moular applications, but has the penalty that you cannot assume closing a connection resolves the transaction.

看来关闭连接也会终止转换。使用简单JDBC时,但是在应用程序服务器中实现的连接池存在时,关闭连接的语义为“返回池”,连接池将保留连接与当前事务的关联。如果稍后在您的代码中,仍然在同一事务的范围内,您要求连接,则池将返回相同的连接。这对于编写moular应用程序非常方便,但是你不能假设关闭连接来解决事务。

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

#3


0  

If you close a connection without committing then it will transaction will be rolled back. if you are using a connection pool, it is probably doing that for you.

如果在未提交的情况下关闭连接,则将回滚事务。如果您正在使用连接池,它可能正在为您执行此操作。

An explicit rollback is probably more appropriate when you encounter a condition that is not causing an exception but you still don't want to commit.

当您遇到不导致异常但仍然不想提交的条件时,显式回滚可能更合适。