Android - 什么时候调用db.setTransactionSuccessful()?

ban*_*ing 11 sqlite android transactions

我见过的Android SQLite事务的代码示例似乎在db.setTransactionSuccessful()之前自动调用db.endTransaction().

我想知道这是否是最佳做法,或者是否应该在打电话之前进行一些有条件的检查db.setTransactionSuccessful().

在我的情况下,我重写ContentProviderbulkInsert()方法,如果我使用描述的条件检查,我的方法将看起来像这样......

    @Override
public int bulkInsert(Uri uri, ContentValues[] valuesArray) {

    // Open a read / write database to support the transaction.
    SQLiteDatabase db = dbHelper.getWritableDatabase();

    switch (uriMatcher.match(uri)) {
        case BRANDS_SEARCH:

            int numInserts = 0;

            db.beginTransaction();

            for (int i = 0; i < valuesArray.length; i++) {

                // Insert the values into the table
                long rowId = db.insert(BRAND_NAMES_TABLE, null, valuesArray[i]);

                if (rowId > -1) {

                    // Increment numInserts
                    numInserts++;

                    // Construct the URI of the newly inserted row.
                    Uri insertedId = ContentUris.withAppendedId(CONTENT_URI_BRANDS, rowId);

                    // Notify any observers of the change in the data set.
                    getContext().getContentResolver().notifyChange(insertedId, null);

                }

            }

            boolean allInsertAttemptsWereSuccessful = (numInserts == valuesArray.length);

            if (allInsertAttemptsWereSuccessful) {
                db.setTransactionSuccessful(); //todo - should this be conditional?
            }
            else {
                //todo - ???
            }

            db.endTransaction();

            return numInserts;

        default:
            //break;
            throw new IllegalArgumentException("Unsupported URI: " + uri);
    }
}
Run Code Online (Sandbox Code Playgroud)

......这是正确的方法吗?

allInsertAttemptsWereSuccessful== false?? 的情况下我应该采取什么行动?

(我查看了Android文档,但提供的信息非常少.)

更新 - 新代码......

感谢laalto的回答,这是我的新(正确)代码......

/**
 * Attempts a bulk insert. Outcome will either be all inserts succeeded
 * or all inserts failed.
 */
@Override
public int bulkInsert(Uri uri, ContentValues[] valuesArray) {

    /*
     *  Open a read / write database to support the transaction.
     */
    SQLiteDatabase db = dbHelper.getWritableDatabase();

    switch (uriMatcher.match(uri)) {
        case BRANDS_SEARCH:

            /*
             * Begin the transaction
             */
            db.beginTransaction();

            try {

                for (int i = 0; i < valuesArray.length; i++) {

                    /*
                     *  Insert the values into the table
                     */
                    long rowId = db.insert(BRAND_NAMES_TABLE, null, valuesArray[i]);

                    if (rowId > -1) {

                        /*
                         *  Construct the URI of the newly inserted row.
                         */
                        Uri insertedId = ContentUris.withAppendedId(CONTENT_URI_BRANDS, rowId);

                        /*
                         *  Notify any observers of the change in the data set.
                         */
                        getContext().getContentResolver().notifyChange(insertedId, null);

                    }
                    else {

                        /*
                         * Give up (as we need all insert attempts to succeed)
                         */
                        throw new Exception("Could not insert row");
                    }

                }

                /*
                 * All insert attempts succeeded
                 */
                db.setTransactionSuccessful();

                return valuesArray.length;
            }
            catch(Exception e) {

                /*
                 * If any insert attempt failed, then setTransactionSuccessful() will not be called so no rows will actually be inserted
                 */
                return 0;

            }
            finally {

                /*
                 * Always end the transaction
                 */
                db.endTransaction();
            }

        default:
            //break;
            throw new IllegalArgumentException("Unsupported URI: " + uri);
    }
}
Run Code Online (Sandbox Code Playgroud)

laa*_*lto 13

交易的规范模式:

beginTransaction();
try {
    //db operations ...

    setTransactionSuccessful();
} finally {
    endTransaction();
}
Run Code Online (Sandbox Code Playgroud)

这可确保endTransaction()始终调用(不会留下悬空事务),并在某些数据库操作中发生异常时回滚事务.如果您想出于自己的原因中止事务,只需不要调用setTransactionSuccessful()或抛出异常.