2017-06-04 76 views
1

有一些我不明白與java.sql.Connection.commit()jdbc autocommit(false)does not work

我使用Derby(Java DB)作爲數據庫服務器。

當我做一個setAutoCommit(false),我希望我的查詢不工作,然後我明確調用commit()方法。 但事實上,即使我沒有調用commit(),它仍然會提交。 當我在我的表上調用select *來打印內容時,我可以看到行已經添加,即使我沒有明確提交查詢。

請問有人能給我一些解釋嗎?

con.setAutoCommit(false); 
    PreparedStatement updateHair = null; 
    PreparedStatement addMan = null; 
    try { 

     String updateString = 
        "update PERSONNE " + 
        "set haircolor = 'RED' where haircolor = 'SHAVE'"; 

     String updateStatement = 
        "insert into personne values " + 
        "(3,'MICHEL','SHAVE')"; 

     addMan = con.prepareStatement(updateStatement); 
     addMan.executeUpdate(); 

     updateHair = con.prepareStatement(updateString); 
     updateHair.executeUpdate(); 

    } catch (SQLException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

回答

2

自動提交意味着每個單獨的SQL語句都被視爲一個事務,並在執行後自動提交。缺省值是SQL語句在完成時提交,而不是在執行時提交。當所有結果集和更新計數已被檢索完成時,語句就完成了。然而,在幾乎所有情況下,一份聲明在執行後即完成並因此承諾。

將兩個或多個語句分組爲事務的方式是禁用自動提交模式。

con.setAutoCommit(false); 

當自動提交模式被禁用時,沒有提交SQL語句直到您顯式調用方法提交。之前調用方法提交後執行的所有語句都包含在當前事務中並作爲一個單元一起提交。

- EDIT_1

更新可能是因爲您要關閉連接,而無需調用rollback()承諾。

如果沒有顯式提交或回滾而關閉Connection,則行爲取決於數據庫。

強烈建議應用程序顯式提交或 在調用close方法之前回滾活動事務。如果 調用close方法並且存在活動事務,則結果是實現定義的。

Connection.close()

+0

感謝,我雖然提交()是假設驗證查詢,如果我沒有使用提交,然後查詢或交易將被忽略,直到我決定明確地提交()。在我的代碼中,我使用了setautocommit(false),因此,如果我從不提交(),在塊的末尾隱式提交將會完成,這是你的意思嗎? –

+0

好吧,我明白了什麼,當我做我的選擇*後,我的插入,我有新聞行添加打印,但如果我停止該程序,然後做一次select *再次,我可以看到只有提交的指令已保存。所以,有一個技巧,commit()將結果保存在數據庫中,但爲什麼我在程序仍在運行時獲得臨時結果? –

+1

@GregArtisi在一個事務中執行的語句可以看到在同一事務中所做的更改。因此,如果您首先插入一行,然後在同一個事務中選擇,您將看到該行(但其他事務不會)。如果你然後回滾事務(例如關閉連接或調用'rollback()'),就好像它從未發生過一樣。 –