android sqlite加入事务批量插入数据异常回滚

本文介绍如何使用SQLite进行高效批量数据插入,并对比了两种不同异常处理方式的影响:一种是在出现异常时回滚所有数据,另一种是仅回滚出现问题的数据,确保其他数据能够继续插入。

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

一、当我们操作sqlite批量插入数据出现异常会回滚的实例:

public  boolean insertBySql(DatabaseHelper openHelper,
                                List<Boy> list,String tname) {
    Log.e("开始时间",System.currentTimeMillis()+"");
    if (null == openHelper || null == list || list.size() <= 0) {
        return false;
    }
    SQLiteDatabase db = null;
    try {
        db = openHelper.getWritableDatabase();
        String sql = "insert into "+tname+"(name,age) values(?,?)";
        SQLiteStatement stat = db.compileStatement(sql);
        db.beginTransaction();//开启事务
        for (Boy boy: list) {
           
                stat.bindString(1, boy.name);
                stat.bindLong(2, boy.age);
        }
        db.setTransactionSuccessful();
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    } finally {
        try {
            if (null != db) {
                db.endTransaction();//事务结束
                db.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    Log.e("结束时间",""+System.currentTimeMillis());
    return true;
}

1、加入事务插入数据,保证访问磁盘只被操作一次,加快了数据插入时间,如不开事务,则出现多次磁盘访问,访问磁盘是比较耗时的操作,所以不开启事务会造成数据插入缓慢

2、以上实例当for循环插入数据出现异常会直接回滚,所有数据插入不成功


二、当我们操作sqlite批量插入数据出现异常做异常处理,会只回滚当前插入不成功的数据,其他数据插入正常进行,代码如下:

public  boolean insertBySql(DatabaseHelper openHelper,
                                List<Boy> list,String tname) {
    Log.e("开始时间",System.currentTimeMillis()+"");
    if (null == openHelper || null == list || list.size() <= 0) {
        return false;
    }
    SQLiteDatabase db = null;
    try {
        db = openHelper.getWritableDatabase();
        String sql = "insert into "+tname+"(name,age) values(?,?)";
        SQLiteStatement stat = db.compileStatement(sql);
        db.beginTransaction();
        for (Boy boy: list) {
            try {
                stat.bindString(1, boy.name);
                stat.bindLong(2, boy.age);
            }catch (Exception e){
                e.printStackTrace();
                Log.e("出错",list.indexOf(boy)+"");
            }

        }
        db.setTransactionSuccessful();
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    } finally {
        try {
            if (null != db) {
                db.endTransaction();
                db.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    Log.e("结束时间",""+System.currentTimeMillis());
    return true;
}
以上实例解决了批量插入时导致数据全部回滚的问题,只对当前插入数据做回滚
### SQLite 批量插入数据的方法 SQLite 支持多种方式执行批量插入操作,这些方法可以显著提升性能并减少资源消耗。以下是几种常用的技术及其具体实现。 #### 使用 `INSERT` 语句配合事务管理 为了提高大批量数据插入的速度,在 SQLite 中应始终将多个插入操作包裹在一个事务中。这可以通过显式开启和提交事务来完成[^2]: ```sql BEGIN TRANSACTION; -- 插入多条记录 INSERT INTO table_name (column1, column2) VALUES (?, ?); INSERT INTO table_name (column1, column2) VALUES (?, ?); COMMIT; ``` 上述代码片段展示了如何通过手动控制事务边界来优化插入过程。每次单独调用 `INSERT` 都会触发日志写入和其他开销;而使用事务则能有效降低这种额外负担。 #### 利用参数化查询与批处理功能 当采用编程语言接口访问 SQLite 数据库(如 Python 或 C),推荐利用其内置支持的批处理机制代替逐行执行命令的方式。例如,在Python环境下可借助`sqlite3`模块里的`executemany()`函数简化流程[^4]: ```python import sqlite3 conn = sqlite3.connect('example.db') cursor = conn.cursor() data_to_insert = [ ('value1', 'value2'), ('value3', 'value4'), ] # 准备SQL模板字符串 query_template = "INSERT INTO mytable(colA, colB) VALUES(?,?)" try: cursor.executemany(query_template, data_to_insert) conn.commit() except Exception as e: print(f"Error occurred: {e}") finally: conn.close() ``` 此脚本定义了一个列表变量存储待加入数据集,并将其传递给`executemany()`方法一次性完成全部录入工作。相比反复调用单次insert而言更加高效快捷。 #### Android 平台下的解决方案 对于基于Android系统的应用程序来说,同样存在针对Sqlite数据库实施高效的大规模资料载入手段。主要思路也是围绕着启用Transaction模式展开讨论[^3]: ```java SQLiteDatabase db = this.getWritableDatabase(); db.beginTransaction(); try { ContentValues values = new ContentValues(); for(int i=0;i<largeDataset.size();i++) { String itemValue = largeDataset.get(i); values.put("ColumnName",itemValue ); db.insertOrThrow(TABLE_NAME,null ,values ); } db.setTransactionSuccessful(); } catch(Exception ex){ Log.e(TAG,"Failed to insert bulk records.",ex); } finally{ db.endTransaction(); } ``` 这里先获取到可写的实例对象后立即启动transaction状态标记。接着循环遍历准备好的大数据集合逐一填充contentValues容器再做实际入库动作直到结束前确认成功与否才决定是否正式生效整个变更序列或者回滚撤销更改以防万一中途出现问题影响整体一致性表现效果不佳的情况发生。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值