2012-08-10 35 views
2

如果使用事務並且sql操作失敗,我知道它會回滾所有更改,但會在finally語句後暫停所有代碼,還是會繼續運行其他代碼?在android中的事務失敗後究竟發生了什麼?

像下面的代碼看起來是否正確或應該使用catch語句?是否有可能爲測試目的而模擬錯誤?

public static boolean updateSuccessful = false; 

updateToVersion2(); 
//Does anything after here still run on error? 

if(!updateSuccessful) { 
    deleteAndRecreateDatabase(); 
} 


public void updateToDbVersion2() { 
    this.myDataBase.beginTransaction(); 
    try { 
     this.myDataBase.execSQL("UPDATE myRecords SET column = 'newValue1' WHERE _id = 1"); 
     this.myDataBase.execSQL("UPDATE myRecords SET column = 'newValue2' WHERE _id = 2"); 
     this.myDataBase.setTransactionSuccessful(); 
     // This is not reached on update error, right? 
     updateSuccessful = true; 
    } finally { 
     this.myDataBase.endTransaction(); 
    } 
} 

回答

0

一個transacti各地本身就是整體行爲。無論是成功的還是失敗的,這意味着您要麼以數據庫的形式獲取所有數據,要麼您什麼都沒有(當然是在這個交易中)。 如果事務在某個時候失敗了,它應該先到達「catch」部分,然後再到「finally」。

正如user827992指出的那樣,捕捉異常是很有趣的。那裏可能會有一些額外的(也許是有價值的)信息。

+0

因此沒有什麼特別的事情發生。它會像其他任何錯誤一樣失敗,但是如果使用事務,它將不會對數據庫進行部分更改。 – Jack 2012-08-12 21:53:16

+0

是的,但仍然推薦使用它們。請注意,數據庫中的每個操作都會打開一個單獨的事務。這個過程大部分時間都在進行。如果你在同一事務之外提交了20個更改到你的數據庫,那麼處理時間將乘以20.如果你在同一個事務中包含所有這些更改,那麼它只需要幾毫秒。 – 2012-08-13 10:34:36

+0

感謝您的信息。我認爲這比實際更復雜。 – Jack 2012-08-15 01:33:57

1

你應該抓住例外!爲什麼你放棄它會使代碼聞起來不好...

如果在execSQLsetTransactionSuccessful之間確實發生了異常並且最終落入您要結束事務的finally部分,該怎麼辦?

的代碼可能是這樣的:

public void updateToDbVersion2() { 
    boolean fubar = false; 
    this.myDataBase.beginTransaction(); 
    try { 
     this.myDataBase.execSQL("UPDATE myRecords SET column = 'newValue1' WHERE _id = 1"); 
     this.myDataBase.execSQL("UPDATE myRecords SET column = 'newValue2' WHERE _id = 2"); 
     this.myDataBase.setTransactionSuccessful(); 
     // This is not reached on update error, right? 
     updateSuccessful = true; 
    } catch(Exception ex){ 
     fubar = true; 
     // Do whatever is needed to be done such as logcat FOR debugging ONLY! 
    } finally { 
     if (!fubar){ 
      // No exceptions occurred, OK to end transaction 
      this.myDataBase.endTransaction(); 
     } 
    } 
} 

注意在finally子句條件檢查如何確保預防潛在的混亂的結果,並確保數據的完整性。

+1

這是必要的嗎?我的理解是,最終將永遠運行,如果endTransaction在沒有setTransactionSuccessful的情況下到達,它將回滾事務 – Jack 2012-08-12 22:08:01