2011-11-03 42 views
8

我想从2个不同的线程访问SQLite数据库,从而使用2个不同的连接到数据库。这两个线程将主要执行从数据库中读取数据,并且仅偶尔写入数据库。如果我觉得这两个线程同时针对数据库写入数据的可能性,我应该感到安全吗?在这种情况下,我不应该有任何问题?SQLite连接和锁定

回答

6

SQLite是线程安全的,最近的版本中,你可以线程之间共享一个连接。也就是说,SQLite FAQ指出“线程是邪恶的”(我不认为它们是指SQLite中的这种情况,而是一般性声明)。

SQLite具有锁定机制,因此即使第二个实例试图获取数据库上的写入锁定,它也会排队等待现有锁定完成,因此即使两个线程正在编写SQLite也应该适应您。常见问题表明,使用不同进程的多个连接网络文件系统通常是不安全的,因为在文件系统中执行的锁定效果不佳,但我认为该警告不适用于您的使用。

+0

谢谢... FAQ是一个很好的资源 –

+0

但我想一个连接将不会有任何并发​​请求数据库,而在@DrakeAmara的情况下,这将是伟大的,如果他有单独的连接,因为这意味着并发访问数据库 – user1530779

0

SQLite显式不是线程安全的,因此如果你这样做,你可以预期数据损坏。

使用互斥锁确保两个线程无法同时访问数据库,或花费数小时试图追踪很少发生且难以重现的幻影数据损坏错误。

http://sqlite.org/faq.html#q5

+4

从文档(http://www.sqlite.org/faq.html# q6):** SQLite是线程安全的** –

9

不完全正确。请在这里看到我的长回复:

What are the best practices for SQLite on Android?

你不会损坏你的数据库,但如果两个不同的线程,有两个不同的连接方式,试图在同一时间写的分贝,你将有问题。一个会“失去”。他们不会等待按顺序运行。如果你调用'insert'而不是'insertOrThrow',你甚至不会得到异常。你只是不会写入数据库。

以下是Android中的Sqlite的工作原理。每个SqliteOpenHelper实例都有1个到数据库的连接。无论您多次调用“getRead/WriteableDatabase”,都无关紧要。一个帮手,一个连接。另外,Android的sqlite连接代码实现了自己的线程锁定,所以如果你使用相同的SqliteOpenHelper,并通过扩展,相同的连接,你会没事的。

但是,如果您使用多个助手,则可能会出现问题。

我怀疑你可以有多个线程阅读,1个写作,出来OK,但我没有测试过这个。

您是否使用多个线程来提高写入性能?如果是这样,我会建议简单地优化您对“交易”的使用。如果你做了多个独立写入,它非常慢。如果你把它们全部包装在一起,它非常快(相对)。我怀疑这是因为每次独立写入时,Android刷新到磁盘(这是非常缓慢的)。如果你在一堆中做了这些改变,所有改变都是在1次写入中完成的。

至于保持1个帮助程序实例,这里是我的一个最近的一篇博客看:

http://touchlabblog.tumblr.com/post/24474750219/single-sqlite-connection

我写了一些相当复杂的引用计数的逻辑,我早落实OrmLite的Android端口的一部分,但在这一点上我不认为这是完全必要的。

http://touchlabblog.tumblr.com/post/24474455802/ormlite-for-android

对于链路完整性,我的博客帖子大约sqlite的锁定和多个连接:

http://touchlabblog.tumblr.com/post/24474398246/android-sqlite-locking

+0

现在这些链接已经死了,你可以发布当前的链接,我真的很有兴趣阅读这些链接。谢谢! – Matthias

+1

你是对的。将需要挖掘,看看我是否有他们。如果他们存在,他们将在http://touchlabblog.tumblr.com –

+0

发现他们,谢谢! – Matthias