2014-09-06 94 views
1

雖然這個問題已經被多次提出,但我仍然不確定。我的設置是這樣的:我使用jdbc並將autocommit設置爲false。假設我有3條插入語句,我想作爲一個事務執行,然後是conn.commit()在jdbc中進行事務時是否調用conn.rollback冗餘?

示例代碼:

try { 
    getConnection() 
    conn.setAutoCommit(false); 
    insertStatment() //#1 
    insertStatment() //#2 
    insertStatment() //#3, could throw an error 
    conn.commit() 
} catch(Sql exception) { 
    conn.rollback() // why is it needed? 
} 

說我有兩個場景

  1. 要麼,不會有任何錯誤,我們會打電話給conn.commit(),一切都將被更新。
  2. 說前兩個語句正常工作,但第三個語句出現錯誤。因此不調用conn.commit(),我們的數據庫處於一致狀態。那麼,爲什麼我需要撥打conn.rollback()

我注意到有人提到回滾會影響連接池嗎?任何人都可以向我解釋,它會如何影響?

回答

1

A rollback()仍然是必要的。不提交或回滾事務可能會保留數據庫上的資源(事務句柄,日誌或記錄版本等)。明確提交或回滾可確保釋放這些資源。

當您繼續使用連接並提交時,未執行顯式回滾可能也會產生不良影響。在事務中成功完成的更改(示例中的#1和#2)將會保留。

但是Connection apidoc確實說「如果自動提交模式已被禁用,則必須顯式調用方法提交以提交更改;否則數據庫更改將不會保存。這應該被解釋爲:一個Connection.close()導致回滾。不過,我相信有一些JDBC驅動程序實現用於在連接關閉時進行提交。

對連接池的影響不應該存在正確實現。關閉從連接池獲得的邏輯連接應該與關閉物理連接具有相同的效果:打開的事務應該被回滾。但是,有時連接池沒有正確實現,或者出於性能原因而出現錯誤或快捷方式,所有這些都可能導致在您從池中獲取邏輯連接時已經開始打開事務。

因此:在調用回滾時要明確。