如何优化SQLiteOpenHelper的错误处理

时间:2012-08-03 10:51:40

标签: android sqliteopenhelper

是否可以使错误处理更清晰,更易读?我的版本看起来有点笨重:

public synchronized void doSomeTrans(...) throws Exception {
    Exception ex = null;
    SQLiteDatabase db = null;
    boolean bTrans = false;

    try {
        db = getWritableDatabase();

        db.beginTransaction();
        bTrans = true;

        db.execSQL(...);
        db.execSQL(...);

        db.setTransactionSuccessful();
    }
    catch (Exception ex1) {
        ex = ex1;
    }

    if (db != null) {
        if (bTrans != false)
            db.endTransaction();

        db.close();
    }

    if (ex != null)
        throw ex;
}

此外,在我的版本中,我没有任何关于endTransaction方法的错误处理,如果此方法抛出异常,我的数据库仍然存在打开。我认为这不好,但不确定在try / catch块上添加new是这种情况的最佳解决方案。

1 个答案:

答案 0 :(得分:2)

如果不出意外,您应该使用finally。无论如何你都在进一步抛出异常,所以不要费心去抓它:

try {
    db = getWritableDatabase();
    ...
} finally {
    if (db != null) {
        if (bTrans != false)
            db.endTransaction();
        db.close();
    }
}

另一件事是您不应该为一个操作打开数据库并再次关闭它,因为那是 SLOW 。您至少应该dbActivity的生命周期Service。哪个摆脱了外getWritableDatabase() / close对,所以你可以选择:

db.beginTransaction();
try {
    db.execSQL(...);
    db.execSQL(...);

    db.setTransactionSuccessful();
} finally {
    db.endTransaction();
}

请注意,如果endTransaction抛出,则无法进入beginTransaction,这很容易发生。我不确定Android包装器,因为我通常使用C API,但C API不等待锁定数据库,但是当数据库已被另一个事务锁定时,它立即失败。

显然RAII或上下文管理器会更短,但不幸的是Java也没有(更新:Java 8确实有try(variable),但Android仍然使用Java 6;但是,它应该在Kotlin中得到支持即使是那个目标)。