android - SQLiteOpenHelper 单连接与多连接

标签 android multithreading sqlite android-sqlite sqliteopenhelper

我对访问 SQLiteDatabase 感到非常困惑。它应该是一个连接或多个连接才能从多个线程访问。我已经阅读了很多文章,包括以下两篇。

https://stackoverflow.com/a/3689883/3027124 http://touchlabblog.tumblr.com/post/24474398246/android-sqlite-locking

这两个都建议使用单一连接。甚至我自己对同一问题的回答也被 OP 接受了。我使用 Singleton 方法访问 SQLiteopenHelper 类。

https://stackoverflow.com/a/35358702/3027124

但是 在阅读了 enableWriteAheadLogging 的文档后我仍然感到困惑

This method enables parallel execution of queries from multiple threads on the same database. It does this by opening multiple connections to the database and using a different database connection for each query. The database journal mode is also changed to enable writes to proceed concurrently with reads.

现在这是令人困惑的部分。如果我想从同时的多个线程访问数据库,我可以使用 Singleton 访问 SQLiteOpenHelper,在我的理解中,这意味着串行执行插入,而同步读取可以在没有 -错误。但是上面的文档说,为了同时访问,应该调用 enableWriteAheadLogging,这会返回创建多个连接。这是怎么回事??如果我通过从多个线程使用 Singleton SQLiteOpenHelper 调用 getWritableDatabase() 来进行插入,这意味着什么?这些电话是串行的吗?是否应该调用 enableWriteAheadLogging

请澄清。

最佳答案

在处理线程时,无论我是否使用 enableWriteAheadLogging,我都会使用单例实例,这在大多数应用程序中都是这种情况,除非它是一个非常微不足道的应用程序,如示例。

使用单例实例可确保线程安全:单例实例可确保跨该实例进行同步,这意味着当您具有从不同线程同时调用数据库的读写方法时,其中一个应该等待另一个,因为数据库在写入时被锁定。

很明显,文档中写的和下面引用的就是这种情况

it is not possible for reads and writes to occur on the database at the same time. Before modifying the database, the writer implicitly acquires an exclusive lock on the database which prevents readers from accessing the database until the write is completed.

enableWriteAheadLogging 实际上改变了上述行为,因为上述语句仅在未启用预写日志记录(默认)时才为真。

那么当您通过 enableWriteAheadLogging 启用预写日志记录时会发生什么?

它实际上是在更改默认行为以启用实际并行性,因为它更改了底层数据库日志文件以允许同时进行写入和读取,但要做到这一点,它需要比平时更多的内存。阅读下面的文档引用以了解更多信息!

In contrast, when write-ahead logging is enabled (by calling this method), write operations occur in a separate log file which allows reads to proceed concurrently. While a write is in progress, readers on other threads will perceive the state of the database as it was before the write began. When the write completes, readers on other threads will then perceive the new state of the database.

It is a good idea to enable write-ahead logging whenever a database will be concurrently accessed and modified by multiple threads at the same time. However, write-ahead logging uses significantly more memory than ordinary journaling because there are multiple connections to the same database. So if a database will only be used by a single thread, or if optimizing concurrency is not very important, then write-ahead logging should be disabled.

关于android - SQLiteOpenHelper 单连接与多连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48265272/

相关文章:

android - 启动器图标显示在模拟器上,但不显示在手机上

android - 如何使用测试绑定(bind)在 Android Studio 中运行 POJO 测试?

c++ - 如果 peek 返回一个引用,即使从未使用过引用(使用程序集!),线程安全队列也不是线程安全的

java - 如何实现 ExecutorService 来轮流执行任务?

python - 为什么在加载模块时使用 Paramiko 会挂起?

sqlite - 在 SQLite 中加入更新

QT - 如何从 QTableView 中的单行获取值

安卓应用风格

android - Android 上适用于 Unity 的 Facebook SDK 尝试在不调用 FB.login 的情况下登录 FB.init

sql - 删除在字符串列中找到的数字