【发布时间】:2014-12-10 07:26:45
【问题描述】:
我有一个 不会改变的 sqlite 数据库。
多个进程使用 sqlite3_open_v2 在 SQLITE_OPEN_READONLY 模式下打开数据库连接。每个进程都是单线程的
连接是使用官方 C/C++ Interface 的单一合并 C 源文件从 MSVC 项目建立的。
根据 SQLite 常见问题解答multiple processes running SELECTs is fine
打开数据库后的每个进程都会创建 4 个准备好的 SELECT 语句,每个语句都有 2 个可绑定值。
在执行过程中,语句(一次一个)会根据需要重复调用以下语句
- sqlite3_bind_int
- sqlite3_bind_int
- sqlite3_step(返回 SQLITE_ROW 时)
- sqlite3_column_int(当有一行时)
- sqlite3_reset
准备好的语句被重用,所以直到程序快结束时才对它们中的每一个调用 finalize。最后,数据库在执行结束时关闭。
问题是任何这些操作都可能失败,error code = 5: 'database is locked'
错误代码 5 是 SQLITE_BUSY,网站声明
“表示与单独的数据库连接发生冲突,可能在单独的进程中”
互联网上的其他人似乎都同意多个 READONLY 连接是可以的。我翻遍了源代码,看不出有什么问题(很遗憾,我不能在这里发布,我知道,没有帮助)
所以我把它交给你们,我可能会错过什么?
编辑 1: 数据库在本地驱动器上,文件系统是 NTFS,操作系统是 Windows 7。
编辑 2: 将所有 sqlite3 调用包装在无限循环中,检查是否返回了 SQLITE_BUSY,然后重新调用可以缓解问题。我不认为这是一个解决办法,但如果这确实是正确的做法,那么我会这样做。
【问题讨论】:
-
在打开数据库之前,尝试调用
sqlite3_config(SQLITE_CONFIG_SERIALIZED)看看会发生什么。 -
或者,在您的
sqlite3_open中执行SQLITE_OPEN_READONLY | SQLITE_OPEN_FULLMUTEX。 -
你在使用 LinQ 吗?
-
QLITE_OPEN_READONLY | SQLITE_OPEN_FULLMUTEX 根本没有帮助。源定义 SQLITE_THREADSAFE 1 所以 sqlite3_config(SQLITE_CONFIG_SERIALIZED) 不会有任何区别,1 是序列化的。