我有一个使用sqlite(3.7.3)
的多线程应用程序我正在点击数据库锁定错误,这似乎非常普遍。 我想知道在我的情况下如何避免它。
让我描述一下我正在建设的内容。对不起,没有代码太大而且复杂。
我有大约8个线程同时访问数据库。这些线程中的任何一个都可以同时读取或写入。
数据库中表中的每一行都有一个指向资源的文件路径+与该资源相关的其他属性。
3个领域是读者,状态和del。
每次线程从资源中读取时,读取器都会递增,但仅当状态为>时才会递增。 0和del = 0.
所以我有一些SQL
UPDATE resource set readers=readers+1 where id=? AND del=0 AND status>0
之后,我检查更新的行数。它应该只有1。 之后我尝试用选择读回行。即使它失败了我也这样做 更新,因为我需要知道它失败的原因。
我尝试在事务中包装更新和select,但这没有帮助。 我已经检查过我正在调用我的陈述。
现在,我认为默认情况下sqlite序列化。我尝试了几种开放模式,但我仍然遇到同样的错误。
在你问之前,不,我不打算去mysql。我绝对需要零配置。
有人可以就如何避免此类问题提供一些指示吗?我应该将读卡器锁移出数据库吗?如果我这样做,我应该用什么机制替换它?我在C ++下使用Linux并且可以使用boost库。
编辑: 有趣的是,在我更新的调用之后添加COMMIT可以显着改善。
答案 0 :(得分:2)
打开数据库时,应配置“忙碌超时”
int sqlite3_busy_timeout(sqlite3*, int ms);
答案 1 :(得分:1)
第一个问题:您是否尝试使用所有八个线程的一个连接?如果是这样,请确保每个线程都有自己的连接。我不知道任何喜欢它的数据库。
另请参阅常见问题解答:http://www.sqlite.org/faq.html
显然SQLite必须使用设置为1的SQLITE_THREADSAFE预处理器选项进行编译。它们确实有一种方法可以确定这是否是您的问题。
另一个问题是写入只能安全地从一个进程发生。