2016-12-01 61 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