避免sqlite3数据库被锁定

时间:2010-11-04 22:05:08

标签: c++ linux sqlite

我有一个使用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可以显着改善。

2 个答案:

答案 0 :(得分:2)

打开数据库时,应配置“忙碌超时”

int sqlite3_busy_timeout(sqlite3*, int ms);

http://www.sqlite.org/c3ref/busy_timeout.html

答案 1 :(得分:1)

第一个问题:您是否尝试使用所有八个线程的一个连接?如果是这样,请确保每个线程都有自己的连接。我不知道任何喜欢它的数据库。

另请参阅常见问题解答:http://www.sqlite.org/faq.html

显然SQLite必须使用设置为1的SQLITE_THREADSAFE预处理器选项进行编译。它们确实有一种方法可以确定这是否是您的问题。

另一个问题是写入只能安全地从一个进程发生。