避免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可以大大改善事情。
当您打开数据库,你应该配置“忙超时”
int sqlite3_busy_timeout(sqlite3*, int ms);
第一个问题:你想使用所有八个线程一个连接?如果是这样,请确保每个线程都有自己的连接。我不知道任何喜欢这个的数据库。
还检查了常见问题解答:http://www.sqlite.org/faq.html
显然的SQLite必须设置为1,他们确实有一种方法来确定,如果这是你的问题SQLITE_THREADSAFE预处理程序选项进行编译。
另一个问题是写入只能从一个进程安全地发生。
是的,每个线程一个连接。我将检查线程安全预处理器选项。尽管如此,我的印象是默认的。 – Matt 2010-11-04 22:41:08
我如何设置此选项? – ademar111190 2013-01-17 14:43:31
提交更经常可以在数据库文件上实现更细粒度的EXCLUSIVE锁,这将减少读者在表中等待解锁的时间。这是以增加的日志文件开销为代价的。查看http://sqlite.org/lockingv3.html#writing了解更多信息。 – checker 2014-02-20 23:58:28