SQLiteOpenHelper 单连接与多连接

Posted

技术标签:

【中文标题】SQLiteOpenHelper 单连接与多连接【英文标题】:SQLiteOpenHelper single connection vs multiple connections 【发布时间】:2018-01-15 14:46:45 【问题描述】:

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

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

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

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

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

此方法可以并行执行来自多个 同一数据库上的线程。它通过打开多个 连接到数据库并使用不同的数据库连接 对于每个查询。数据库日志模式也更改为启用 写入与读取同时进行。

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

请澄清。

【问题讨论】:

您需要SQLiteDatabase#enableWriteAheadLogging 的用例是什么? “开始事务”或“sql-insert/update/delete”上的默认(无预写日志记录)阻止进一步读/写线程,直到事务执行完成,所以这应该是线程安全的。 【参考方案1】:

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

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

很明显,这是文档中所写并在下面引用的情况

它不是 数据库上可能同时发生读取和写入 时间。在修改数据库之前,writer 隐式获取一个 数据库上的排他锁,阻止读者访问 数据库,直到写入完成。

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

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

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

相反,当启用预写日志记录时(通过调用此 方法),写操作发生在一个单独的日志文件中,它允许 读取以同时进行。在写入过程中,读者 在其他线程上将按原样感知数据库的状态 在写开始之前。写入完成后,其他阅读器 然后线程将感知数据库的新状态。

每当数据库出现时启用预写日志记录是个好主意 将被多个线程同时访问和修改 同时。但是,预写式日志记录使用显着更多的内存 比普通的日记,因为有多个连接到 同一个数据库。所以如果一个数据库只被一个线程使用, 或者如果优化并发不是很重要,那么预写 日志记录应该被禁用。

【讨论】:

我正在使用Singleton,但我的意思是,如果我使用enableWriteAheadLogging 并同时从多个线程调用getWritableDatabase,这不应该是一个问题,因为有多个连接而不是单个? 是的,没有问题,这是由数据库内部处理的,因为有一个连接池,在设置WAL时会启动***.com/questions/29062967/…

以上是关于SQLiteOpenHelper 单连接与多连接的主要内容,如果未能解决你的问题,请参考以下文章

java 单例模式与多线程

NotORM 的连接与多选

zookeeper的c API 单线程与多线程问题 cli_st和cli_mt

如何在plotly python中将箱形图中位数与多类别x轴连接起来

如何操作android中的数据库

前端八股文浏览器系列:单进程与多进程浏览器进程异步事件循环同源策略输入URL回车后TCP三次挥手四次握手