Android SQLite数据库

在进行数据库操作时,不可避免的问题是批量操作如何保证速度。有关这个问题我做了一组测试,下边直接上代码。
方式一:

        long start = SystemClock.elapsedRealtime();
        Log.i(TAG, "testInsert: 开始");
        for (int i = 0; i < 9999; i++) {
            Student student = new Student("" + i, 16 + i % 10);
            DBHelper.getInstance().insertStudent(student);
        }
        Log.i(TAG, "testInsert: " + (SystemClock.elapsedRealtime() - start));

测试结果:

I/MainActivity: testInsert: 开始
I/MainActivity: testInsert: 13184

方式二:

        long start = SystemClock.elapsedRealtime();
        Log.i(TAG, "testInsert: 开始");
        DBHelper.getInstance().getDb().beginTransaction();
        for (int i = 0; i < 9999; i++) {
            Student student = new Student("刘" + i, 16 + i % 10);
            DBHelper.getInstance().insertStudent(student);
        }
        DBHelper.getInstance().getDb().setTransactionSuccessful();
        DBHelper.getInstance().getDb().endTransaction();
        Log.i(TAG, "testInsert: " + (SystemClock.elapsedRealtime() - start));

测试结果:

I/MainActivity: testInsert: 开始
I/MainActivity: testInsert: 366

测试表明开启事务的速度反而更快。

原因:
android.database.sqlite.SQLiteSession的类注释:

 * <h2>Transactions</h2>
 * <p>
    <!--两种事务,隐式事务和显式事务-->
 * There are two kinds of transaction: implicit transactions and explicit
 * transactions.
 * </p><p>
    <!--重点-->
    <!--重点-->
    <!--重点-->
    <!--当数据库操作没有显式事务时,会自动添加一个隐式事务,这个隐式事务只持续本次操作,然后会立刻结束,如果操作成功,就会提交事务-->
 * An implicit transaction is created whenever a database operation is requested
 * and there is no explicit transaction currently in progress.  An implicit transaction
 * only lasts for the duration of the database operation in question and then it
 * is ended.  If the database operation was successful, then its changes are committed.
 * </p><p>
 * An explicit transaction is started by calling {@link #beginTransaction} and
 * specifying the desired transaction mode.  Once an explicit transaction has begun,
 * all subsequent database operations will be performed as part of that transaction.
 * To end an explicit transaction, first call {@link #setTransactionSuccessful} if the
 * transaction was successful, then call {@link #end}.  If the transaction was
 * marked successful, its changes will be committed, otherwise they will be rolled back.
 * </p><p>
 * Explicit transactions can also be nested.  A nested explicit transaction is
 * started with {@link #beginTransaction}, marked successful with
 * {@link #setTransactionSuccessful}and ended with {@link #endTransaction}.
 * If any nested transaction is not marked successful, then the entire transaction
 * including all of its nested transactions will be rolled back
 * when the outermost transaction is ended.
 * </p><p>
 * To improve concurrency, an explicit transaction can be yielded by calling
 * {@link #yieldTransaction}.  If there is contention for use of the database,
 * then yielding ends the current transaction, commits its changes, releases the
 * database connection for use by another session for a little while, and starts a
 * new transaction with the same properties as the original one.
 * Changes committed by {@link #yieldTransaction} cannot be rolled back.
 * </p><p>
 * When a transaction is started, the client can provide a {@link SQLiteTransactionListener}
 * to listen for notifications of transaction-related events.
 * </p><p>
 * Recommended usage:
 * <code><pre>
 * // First, begin the transaction.
 * session.beginTransaction(SQLiteSession.TRANSACTION_MODE_DEFERRED, 0);
 * try {
 *     // Then do stuff...
 *     session.execute("INSERT INTO ...", null, 0);
 *
 *     // As the very last step before ending the transaction, mark it successful.
 *     session.setTransactionSuccessful();
 * } finally {
 *     // Finally, end the transaction.
 *     // This statement will commit the transaction if it was marked successful or
 *     // roll it back otherwise.
 *     session.endTransaction();
 * }
 * </pre></code>
 * </p>

重点在于,如果没有开启显式事务,数据库会为每次操作添加一个默认的隐式事务。

    原文作者:天街孤独
    原文地址: https://www.jianshu.com/p/3cb5d030df4a
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞