2012-09-13 66 views
5

從池中獲取db連接(conn)。在conn.commit()後需要setautocommit(true)

假設該連接上的autocommit爲TRUE。

Now conn.setautocommit(false) has set;

然後幾句話更新,最後conn.commit()/conn.rollback()已經完成。

現在我需要做明確的代碼setautocommit(true)恢復到以前的conn狀態嗎?

commit()\rollback()固有地設置setautocommit(true)

回答

7

這取決於你從哪裏獲得連接。如果您自己創建連接,則不需要恢復自動提交的狀態。

如果您從數據源獲得該數據,則應該將狀態恢復爲,因爲數據源可能會將連接保留在池中,並且下一段代碼可能不會期望您設置的內容。

commit()不會影響自動提交的值。啓用自動提交只是確保JDBC驅動程序在執行每條語句後調用commit()。您仍然可以隨時撥打commit(),只是不會有任何效果(除rollback()不會始終按照您的要求)。

[編輯]如何處理自動提交取決於您的連接池。 dbcp有一個配置選項可在您給予連接前關閉自動確認功能,c3p0會在您返回池時回滾連接。閱讀連接池的文檔,瞭解它的工作原理。

如果您不知道使用哪個池,則安全的解決方案是,每當您獲得連接時將自動提交設置爲false,並在出現異常時回滾連接。我建議寫一個包裝:

public <T> T withTransaction(TxCallback<T> closure) throws Exception { 
    Connection conn = getConnection(); 
    try { 
     boolean autoCommit = conn.getAutoCommit(); 
     conn.setAutoCommit(false); 

     T result = closure.call(conn); // Business code 

     conn.commit(); 
     conn.setAutoCommit(autoCommit); 
    } catch(Exception e) { 
     conn.rollback(); 
    } finally { 
     conn.close(); 
    } 
} 

此代碼將正確處理您的連接,您不必再擔心業務代碼中的問題。

+0

連接池本身負責恢復返回連接的autoCommit()狀態。這不是檢索連接的人的責任。 –

+0

@MarkRotteveel:參考? –

+0

@AaronDigulla您能詳細解釋一下「rollback()會不會總是做你想做的事嗎?」 –

0

conn.setAutoCommit(autoCommit);應該移至finally塊

相關問題