请告诉我们何时需要调用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 );
}
在上面的代码中我们没有使用connection.rollback(),但是如果发生了一些异常,即使这样一切都会正常工作[我猜],cos连接已经在autoCommit = false模式下设置了。
那么当我们需要使用这种方法时可能出现的情况。请发布示例。
答案 0 :(得分:5)
当您关闭连接时,您的交易将被终止。大多数DBMS会回滚你的交易,因为他们不知道在什么情况下连接被终止(可能你的程序被杀了?)。因此,如果您已经提交,则回滚将不执行任何操作。
另一方面,如果您正在使用Connection-Pooling,当您关闭连接时,Pool Manager会拦截它,并且可能(希望)回滚连接并保持连接处于打开状态。
最好在catch子句内部回滚,甚至在finally子句中回滚。提交后进行不必要的回滚通常没什么坏处。
顺便说一句,如果您使用Postgres,最好在开始之前回滚以确保重置事务开始时间。那是因为Postgres将current_timestamp值保存到事务开始的时间,如果你使用池化连接,这可能是很久以前了!
答案 1 :(得分:4)
在例外情况下,您的交易未得到解决。最终会超时,正如你所说它会回滚。但在此之前(可能是几分钟),您的交易所持有的所有锁都将被保留。连接无法实现您可能不只是commit()。像这样长时间持有锁是非常适合并发的。
将回滚添加到例外情况。
关闭连接似乎也会终止转换。使用简单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
答案 2 :(得分:0)
如果在未提交的情况下关闭连接,则将回滚事务。如果你正在使用连接池,它可能正在为你做这件事。
当您遇到不会导致异常但仍然不想提交的条件时,显式回滚可能更合适。