sqlite db保持锁定/不可访问

时间:2011-10-14 09:07:19

标签: c++ database linux sqlite

我遇到一个sqlite3数据库的问题,在某次访问后仍然无法访问。

到目前为止,行为发生在Ubuntu 10.4和自定义(OpenEmbedded)Linux上。 sqlite版本是3.7.7.1)。 Db是本地文件。

One C ++ - 应用程序定期访问db(5s)。每次在延迟事务中完成几个insert语句。这只发生在一个线程中。与db的连接在应用程序的整个生命周期内保持。使用的语句也是持久的,并通过sqlite3_reset重用。 sqlite_threadsafe设置为1(序列化),日记设置为WAL。

然后我使用sqlite命令行工具在parellel中打开sqlite db。我输入BEGIN IMMEDIATE;,等待> 5s,然后使用END;提交。

之后,应用程序的db访问失败:BEGIN TRANSACTION返回返回码1(“SQL错误或缺少数据库”)。如果我在开始之前执行ROLLBACK TRANSACTION,为了确保没有活动事务,它将失败并返回代码5(“数据库文件被锁定”)。

有没有人知道如何解决这个问题,或者知道可能导致这个问题的原因?

编辑:有一种解决方法:如果发生上述错误,我会关闭并重新打开数据库连接。这解决了这个问题,但我现在不知道为什么会这样。

2 个答案:

答案 0 :(得分:0)

Sqlite是一个服务器较少的数据库。据我所知,它不支持多个源的并发访问。您正尝试从应用程序和命令工具访问相同的后备文件 - 因此您尝试执行并发访问。这就是它失败的原因。

答案 1 :(得分:0)

SQLite连接只能在单线程中使用,因为它们包含用于确保正确并发访问的互斥锁。 (请注意,SQLite也始终只支持单个更新线程,并且当时没有并发读取;这是无服务器数据库的限制。)

幸运的是,当他们没有做任何事情时,SQLite连接相对便宜,而缓存准备语句之类的事情的成本实际上相当小;尽可能多地开放。

[编辑]: 此外,这将解释关闭和重新打开连接的工作原理:它在新线程中构建连接(并完成旧线程中的所有锁等)。