Android SQLite 显式事务控制优化插入数据

来源:互联网 发布:主播直播软件 编辑:程序博客网 时间:2024/06/16 16:02

问题:

有的时候使用Android原数据库SQLite,通常我们在插入数据库是这样的:

    private boolean addDataSet(SQLiteDatabase db, DataOneLogFileDecorator dataSet) {        ContentValues values = new ContentValues();        int countData = dataSet.getDataDecoratorsList().size();        Logger.d("count Data = "+countData);        try {            for (int i = 0; i < countData; i++) {                values.clear();                values.put(DataTable.ExitDataOri.F_fileName, dataSet.getLogFileName());                values.put(DataTable.ExitDataOri.F_fileHash, dataSet.getLogFileHash());                                ExitDataDecorator exitDataDecorator = (ExitDataDecorator)dataSet.getDataDecoratorsListItem(i);                values.put(DataTable.ExitDataOri.F_pkg, exitDataDecorator.getPackageName());                values.put(DataTable.ExitDataOri.F_cls, exitDataDecorator.getClassName());                values.put(DataTable.ExitDataOri.F_isHome, exitDataDecorator.getIsHome());                values.put(DataTable.ExitDataOri.F_startTime, exitDataDecorator.getStartTime());                values.put(DataTable.ExitDataOri.F_exitTime, exitDataDecorator.getKeyValueExitTime());                //Logger.d("insert count = "+i);                db.insert(DataTable.ExitDataOri.TABLE_NAME, null, values);            }        } catch (Exception e) {            // TODO: handle exception            Logger.d("insert have a issue on file log");            e.printStackTrace();        } finally{                    }                return true;    }

1.这种情况,如果数据过多,加入countData = 10000 , 那么db.insert()函数就会执行10000次, 默认这里就是 一万个 事务, 读写磁盘一万次。

2.这种情况也会出现一部分数据写进数据库了,而另外一部分还没写进数据库,数据库混乱了,这也系不是我们本意想要的。

这极大的浪费了时间,同时解决此混乱。我们完全可以 一次读写磁盘的操作把一万条数据全部写进磁盘; 要么全写进,要么全没写进数据库。从而优化APP性能 和 更健壮。


优化方式:

手动设置事务控制。

使用SQLiteDatabase的beginTransaction()方法可以开启一个事务,程序执行到endTransaction() 方法时会检查事务的标志是否为成功,如果程序执行到endTransaction()之前调用了setTransactionSuccessful() 方法设置事务的标志为成功则提交事务,如果没有调用setTransactionSuccessful() 方法则回滚事务。


如:

    private boolean addDataSet(SQLiteDatabase db, DataOneLogFileDecorator dataSet) {        ContentValues values = new ContentValues();        int countData = dataSet.getDataDecoratorsList().size();        Logger.d("count Data = "+countData);        try {            db.beginTransaction();// start transaction            for (int i = 0; i < countData; i++) {                values.clear();                values.put(DataTable.LaunchDataOri.F_fileName, dataSet.getLogFileName());                values.put(DataTable.LaunchDataOri.F_fileHash, dataSet.getLogFileHash());                                LaunchDataDecorator dataDecorator = dataSet.getDataDecoratorsListItem(i);                values.put(DataTable.LaunchDataOri.F_pkg, dataDecorator.getPackageName());                values.put(DataTable.LaunchDataOri.F_cls, dataDecorator.getClassName());                values.put(DataTable.LaunchDataOri.F_firstBoot, dataDecorator.isFirstBoot());                values.put(DataTable.LaunchDataOri.F_startTimeStamp, dataDecorator.getStartTimePoint());                values.put(DataTable.LaunchDataOri.F_bindAppTime, dataDecorator.getKeyValueBindAppTime());                values.put(DataTable.LaunchDataOri.F_input, dataDecorator.getKeyValueInputTimePoint());                values.put(DataTable.LaunchDataOri.F_onCreate, dataDecorator.getKeyValueOnCreateTime());                values.put(DataTable.LaunchDataOri.F_onStart, dataDecorator.getKeyValueOnStartTime());                values.put(DataTable.LaunchDataOri.F_onResume, dataDecorator.getKeyValueOnResumeTime());                values.put(DataTable.LaunchDataOri.F_responseTime, dataDecorator.getKeyValueResponseTime());                values.put(DataTable.LaunchDataOri.F_animationTime, dataDecorator.getKeyValueAnimationTime());                values.put(DataTable.LaunchDataOri.F_animationDone, dataDecorator.getKeyValueAnimationDoneTimePoint());                //Logger.d("insert count = "+i);                db.insert(DataTable.LaunchDataOri.TABLE_NAME, null, values);            }            db.setTransactionSuccessful();// set transaction flag        } catch (Exception e) {            // TODO: handle exception            e.printStackTrace();        } finally{            values.clear();            db.endTransaction();// if success commit the transaction, if no success roll back the transaction        }                return true;    }

后记:

增删改查,类似于这样的事物均可以这样优化。




0 0