我遇到一个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(“数据库文件被锁定”)。
有没有人知道如何解决这个问题,或者知道可能导致这个问题的原因?
编辑:有一种解决方法:如果发生上述错误,我会关闭并重新打开数据库连接。这解决了这个问题,但我现在不知道为什么会这样。
答案 0 :(得分:0)
Sqlite是一个服务器较少的数据库。据我所知,它不支持多个源的并发访问。您正尝试从应用程序和命令工具访问相同的后备文件 - 因此您尝试执行并发访问。这就是它失败的原因。
答案 1 :(得分:0)
SQLite连接只能在单线程中使用,因为它们包含用于确保正确并发访问的互斥锁。 (请注意,SQLite也始终只支持单个更新线程,并且当时没有并发读取;这是无服务器数据库的限制。)
幸运的是,当他们没有做任何事情时,SQLite连接相对便宜,而缓存准备语句之类的事情的成本实际上相当小;尽可能多地开放。
[编辑]: 此外,这将解释关闭和重新打开连接的工作原理:它在新线程中构建连接(并完成旧线程中的所有锁等)。