2016-12-01 58 views
-1

在SQLite升級過程中,失敗事務後,drop table沒有做任何事情。刪除SQL不會引發異常。Android SQLite - 升級過程中失敗事務後丟失表

我可以讓這個工作的唯一方法是刪除與交易有關的所有事情,但我希望數據庫保持不變,以分析升級過程中出錯的原因。

private void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){ 
    try { 
     db.beginTransaction(); 
     // Exception occurs here 
     db.setTransactionSuccessful(); 
     db.endTransaction(); 
    }catch(Exception e){ 
     db.endTransaction(); // Transaction is unsuccessful and changes rolled back 
     // Save for analyses 
     db.execSQL("DROP TABLE ..."); // Drop table does nothing 
    } 
} 

回答

0

onUpgrade已經在事務塊中。爲了使這個工作如何我想要它(雖然它結束了它沒有開始的交易):

// Path to db on local storage 
private String mDbToUpload = null; 

@Override 
private void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){ 
    try { 
     // Exception occurs here 
    }catch(Exception e){ 
     db.endTransaction(); // End transaction to rollback changes 
     mDbToUpload = ...// Save db to local storage 
    } 
} 

@Override 
private void onOpen(SQLiteDatabase db){ 
    if(mDbToUpload != null){ 
    ... // Upload db from path 
    mDbToUpload = null; 
    } 
} 
0

刪除表查詢在您調用endtransaction後執行。檢查該訂單。這可能是原因。

+0

我需要它在結束事務後執行,以便從事務的變化回滾。 – Ryan

+0

endtransaction將履行回滾責任。對? –

+0

爲什麼在最終放棄完整表時回滾更改 – Nitesh

0

是beingTransaction或rollbackTransaction之間什麼樣的代碼,如果是execSQL(),你需要捕捉異常SQLException,如果您使用的插入,用insertOrThrow(),請不要指望Exception e將捕獲所有異常..

+1

這只是示例代碼。無論什麼異常拋出,只要事務回滾並且表被刪除。無論哪種方式,這將不會像SQLException派生自Exception,請參閱https://docs.oracle.com/javase/7/docs/api/java/sql/SQLException.html – Ryan

1

SQLiteOpenHelper生命週期方法(如onUpgrade())在事務中執行。 sqlite不支持嵌套事務,並且Android的SQLiteDatabase僅使用引用計數來模擬嵌套事務,但這種模擬的嵌套事務實際上並不是真正的事務。

如果您在生命週期方法中遇到問題,請拋出異常,框架將爲您回滾最外面的實際事務。

+0

完美!這是我正在尋找的。 https://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html#onUpgrade(android.database.sqlite.SQLiteDatabase,int,int) 你知道無論如何要運行一個特定的作品升級失敗後的代碼? – Ryan

+0

您可以在'onUpgrade()'上捕獲並重新拋出異常' – laalto

+0

這意味着要在調用getWriteableDatabase'的地方捕獲異常,對吧? – Ryan