SQLiteOpenHelper单连接与多个连接

问题描述 投票:3回答:1

关于访问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的文件后,我仍然感到困惑

此方法允许从同一数据库上的多个线程并行执行查询。它通过打开与数据库的多个连接并为每个查询使用不同的数据库连接来完成此操作。数据库日志模式也会更改为允许写入与读取同时进行。

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

请澄清。

android multithreading sqlite android-sqlite sqliteopenhelper
1个回答
2
投票

我会使用单例实例,无论我是否在处理线程时使用enableWriteAheadLogging,大多数应用程序就是这种情况,除非它是一个非常简单的应用程序,如样本。

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

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

读取和写入不可能同时在数据库上进行。在修改数据库之前,writer会隐式获取数据库上的独占锁,这会阻止读者在写入完成之前访问数据库。

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

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

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

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

每当数据库同时被多个线程同时访问和修改时,最好启用预写日志记录。但是,预写日志记录比普通日记记录使用更多内存,因为有多个连接到同一个数据库。因此,如果数据库仅由单个线程使用,或者如果优化并发性不是很重要,则应禁用预写日志记录。

© www.soinside.com 2019 - 2024. All rights reserved.