2009-09-01 74 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

如果你關閉一個沒有提交的連接,那麼事務將被回滾。如果您使用的是連接池,則可能是爲您做的。當您遇到不會導致異常的情況,但你還是不想犯

一個明確的回滾可能是比較合適的。

相關問題