SQLite 不立即插入记录

Posted

技术标签:

【中文标题】SQLite 不立即插入记录【英文标题】:SQLite not inserting record instantly 【发布时间】:2020-10-08 02:55:53 【问题描述】:

我正在开发一个应用程序,该应用程序在收到付款后将交易保存在 SQLite 数据库中。 一旦交易被批准,它就会被插入到数据库中,并且在该用户显示批准之后。 当我得到结果时,我表示批准 sqlitedatabase.insert() 方法,并检查它是否返回行号。

public static boolean insert(String tableName, SQLiteDatabase sqLiteDatabase, ContentValues contentValues)
        long rowId = sqLiteDatabase.insert(tableName, null, contentValues);
        return rowId != -1;
    

问题是,当向用户显示批准时,我通过弹出电池关闭设备(我正在测试电池盒)并且 当我重新启动设备时,我看到数据库中没有插入记录。这让我觉得 SQLite 在返回行 ID 后异步插入记录。

我正在使用 AsyncTask,我在 doInBackground 中插入,并在 AsyncTask 的 onPostExecute() 中显示用户批准。

我的问题是,有什么方法可以确保在我调用 insert 方法时插入记录,还是我在这里做错了什么?

【问题讨论】:

使用 Worker's(WorkManager) 可以为您解决这个问题,并确保在给定条件下完成任务。 @Anmol 我认为这与此无关,我的任务已经完成并调用 onPostExecute。 你能在插入后尝试 database.setTransactionSuccessful() - 将当前事务标记为成功。它可以保证记录插入。 是否插入了记录?我的意思是,如果你不弹出电池,什么时候会出现记录? 直到事务没有结束,命令可能不会被硬写。尝试开始事务,执行插入,关闭事务,然后取出电池。 【参考方案1】:

经过一番研究,我意识到是什么导致了问题。 这是 SQLite 的默认配置设置,同步设置不是 FULL。根据documentation:

FULL (2) 当同步为 FULL (2) 时,SQLite 数据库引擎将 使用 VFS 的 xSync 方法确保所有内容安全 在继续之前写入磁盘表面。 这可确保 操作系统崩溃或电源故障不会损坏数据库。 FULL 同步非常安全,但速度也较慢。 FULL是最 非 WAL 模式下常用的同步设置。

默认配置不完整,我在我的 SQLiteOpenHelper 类的 onConfigure 回调中更改了它。它解决了这个问题。

@Override
public void onConfigure(SQLiteDatabase db) 
    db.execSQL("PRAGMA synchronous = 2");

虽然文档声明“FULL 同步非常安全,但速度也较慢。”,尽管在某些情况下批量插入,但我没有看到明显的性能差异。

【讨论】:

以上是关于SQLite 不立即插入记录的主要内容,如果未能解决你的问题,请参考以下文章

带有 FMDB 包装器的 Sqlite 数据库不插入数据

如果它已经在表中,如何不在sqlite中记录[关闭]

如何使用 sqlite 批量插入超过 1000 条记录?

将数据插入SQLite表后如何获取最后一行ID [重复]

如何在 SQLite 表中插入日期和查询日期

使用 Django 将数千条记录插入 SQLite 表的有效方法是啥?