天天看點

SQLite的事務操作

sqlite中常常需要對大量資料批量操作。若使用for循環方法,效率較低。因為 sqlite操作資料的時候預設一條語句就是一個事務,有多少條資料就有多少次磁盤操作。10000條記錄就要進行10000次讀寫磁盤操作,而且不能保證所有資料都能成功操作。(有可能部分成功,另外一部分失敗,後續還得删除。太麻煩)

解決方法:

添加事務處理,把10000條資料操作作為一個事務。這樣可大幅度提高操作速度,往往效率高出10倍左右。

主要用到以下三個方法:

(1)開始事務

db.beginTransaction();

(2)循環完畢後,設定實務操作成功為true

db.setTransactionSuccessful();

(3)在finally語句中結束事務

db.endTransaction();

如果程式執行到endTransaction之前調用了 setTransactionSuccessful方法設定事務的标志為成功,則送出事務;如果沒有調用setTransactionSuccessful方法則復原事務。

使用事務,可以避免程式因為出錯而終止運作,例如下面轉款的例子。如果ATM機在轉款過程中挂掉,通過事務處理可以防止之前運作結果的改變。

public void testTransaction() {
        PersonSQLiteOpenHelper openHelper = new PersonSQLiteOpenHelper(getContext());
        SQLiteDatabase db = openHelper.getWritableDatabase();
        if (db.isOpen()) {
            try {
                //開啟事務
                db.beginTransaction();
                //1.從張三賬戶中扣1000塊錢
                db.execSQL("update person set balance = balance - 1000 where name = 'zhangsan';");
                //ATM機挂掉了
                int result = /;
                //向李四賬戶中加1000塊錢
                db.execSQL("update person set balance = balance + 1000 where name = 'lisi';");
                //标記事務成功
                db.setTransactionSuccessful();
            } finally {
                //停止事務
                db.endTransaction();
            }
        }

    }
           

下面是對10000條資料批處理的例子。

public void testTransactionInsert() {
        PersonSQLiteOpenHelper openHelper = new PersonSQLiteOpenHelper(getContext());
        SQLiteDatabase db = openHelper.getWritableDatabase();
        if (db.isOpen()) {

            //1.記住目前的時間
            long start = System.currentTimeMillis();
            //2.開始添加資料
            try {
                db.beginTransaction();
                for (int i = ; i<; i++) {
                    db.execSQL("insert into person(name,age,balance) values ('wang"+i+"',"+(+i)+","+(+i)+")");
                }
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
            //3.記住結束時間,計算耗時
            long end = System.currentTimeMillis();
            long diff = end - start;

            db.close();
        }
    }