0

是否有可能让错误处理更清晰、更易读?我的版本似乎有点笨重:

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 块上添加新内容是这种情况下的最佳解决方案。

4

1 回答 1

2

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

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

另一件事是您不应该为一个操作打开数据库并再次关闭它,因为那是SLOW。您应该db至少在Activityor的整个生命周期内都可以使用Service。它摆脱了外部getWritableDatabase()/close对,因此您可以:

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

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

请注意,这并没有涉及到endTransactionif beginTransactionthrows,这很容易发生。我不确定Android包装器,因为我通常使用C API,但是C API不会等待锁定数据库,而是当数据库已经被另一个事务锁定时立即失败。

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

于 2012-08-03T11:10:31.923 回答