2009-09-01 73 views
2

请让我知道我们什么时候需要调用方法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); 
} 

在上面的代码中,我们没有使用connection.rollback(),但如果出现一些异常,甚至那么一切都将正常工作[我猜],COS连接在自动提交=虚假模式已设置。

那么当我们需要使用这种方法时可能会出现什么情况。请张贴示例。

+0

简单的回答:程序员不应该手动调用rollback()或commit()。 – SteveD 2009-09-02 10:14:15

+0

除了学习JDBC,编写库/框架或者做一些关键性能,我不会推荐使用原始JDBC--使用Spring,JPA或其他框架来自动处理事务和连接。这太容易搞砸了互动,并有大量的样板代码。 – SteveD 2009-09-02 10:17:43

回答

4

当您关闭连接时,您的交易将被终止。大多数DBMS会回滚你的事务,因为他们不知道在什么情况下连接被终止(也许你的程序被杀了?)。所以,如果你已经犯下了错误,回滚将无能为力。

在另一方面,如果你使用连接池,当你关闭连接池管理器拦截它,可能会(希望)回滚的连接,并使连接打开。

在catch子句内或甚至在finally子句中回滚是一种很好的做法。在提交之后进行不必要的回滚通常不会造成伤害。另外,如果您使用的是Postgres,在启动之前最好先回滚,以确保重置您的交易开始时间。这是因为Postgres将current_timestamp值保存到事务开始时,并且如果您使用的是连接池,这可能很久以前了!

+1

在某些应用程序服务器中存在连接池时,关闭连接将**不回滚事务。这是一个故意的性能优化,这意味着连接的第二次打开实际上会给与**相同的连接,仍然与trasnaction相关联。 – djna 2009-09-02 06:56:16

4

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

将回滚添加到您的例外情况。

可能会出现关闭连接也会终止转换。当使用简单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 
+0

会超时吗?我觉得安静最后会放弃交易 – 2009-09-01 11:28:00

+0

是的它会在连线池的前提下。我已经扩大了答案,试图做到这一点 – djna 2009-09-02 06:53:39

0

如果你关闭一个没有提交的连接,那么事务将被回滚。如果您使用的是连接池,则可能是为您做的。当您遇到不会导致异常的情况,但你还是不想犯

一个明确的回滚可能是比较合适的。

相关问题