避免sqlite3的数据库锁定

问题描述:

我有使用SQLite(3.7.3)避免sqlite3的数据库锁定

我打的数据库锁定错误,这似乎是相当普遍的多线程应用程序。 我想知道如何避免它在我的情况。

让我来描述一下我正在建造的东西。对不起,没有代码太大又复杂。

我有大约8个线程同时访问数据库。这些线程中的任何一个都可以同时读取或写入。

数据库表中的每一行都有一个文件路径,指向一个资源+与该资源相关的其他属性。

3个值得注意的领域是读者,状态和del。

读者是每个线程从资源读取时间增加,但只有当状态> 0,德尔= 0

让我有些SQL,做

UPDATE resource set readers=readers+1 where id=? AND del=0 AND status>0 

在那之后,我检查更新的行数。它应该只有1. 之后,我尝试用select读取行。我这样做,即使它不能更新 ,因为我需要知道它失败的原因。

我尝试在事务中包装更新和选择,但没有帮助。 我已经检查过,我也打电话给我的发言。

现在,我认为sqlite默认序列化。我尝试了几个开放模式,但我仍然得到相同的错误。

在你问之前,不,我不打算去mysql。我绝对需要零配置。

有人可以提供一些关于如何避免这种类型的问题的指针吗?我应该将阅读器锁定在数据库之外吗?如果我这样做,我应该用什么机制来替代它?我在C++下使用Linux,并使用boost库。

编辑: 有趣的是,在更新后的呼叫中添加COMMIT可以大大改善事情。

+1

提交更经常可以在数据库文件上实现更细粒度的EXCLUSIVE锁,这将减少读者在表中等待解锁的时间。这是以增加的日志文件开销为代价的。查看http://sqlite.org/lockingv3.html#writing了解更多信息。 – checker 2014-02-20 23:58:28

当您打开数据库,你应该配置“忙超时”

int sqlite3_busy_timeout(sqlite3*, int ms); 

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

+2

嗨,是的,我试过了。它有一点帮助。但即使设置为1秒钟,它仍然会遇到锁定问题。我已启用shared_cache模式,这似乎有助于比繁忙的超时。我会尝试两种。 – Matt 2010-11-04 22:22:09

+0

原来,对于我的应用程序来说,sqlite正在遭受严重打击。所以我把阅读器领域转移到了记忆中。这已经提高了大约10000%的性能,而且我的硬盘更少了。 – Matt 2010-11-08 21:13:52

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

还检查了常见问题解答:http://www.sqlite.org/faq.html

显然的SQLite必须设置为1,他们确实有一种方法来确定,如果这是你的问题SQLITE_THREADSAFE预处理程序选项进行编译。

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

+0

是的,每个线程一个连接。我将检查线程安全预处理器选项。尽管如此,我的印象是默认的。 – Matt 2010-11-04 22:41:08

+0

我如何设置此选项? – ademar111190 2013-01-17 14:43:31