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

本文介绍在Android应用中使用SQLite数据库进行大量数据插入时的优化方法。通过使用事务控制减少磁盘I/O操作次数,确保数据一致性,并提升应用程序性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题:

有的时候使用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;
    }

后记:

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




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卜溪大人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值