【发布时间】:2011-05-05 08:22:57
【问题描述】:
我有一个使用 sqlite (3.7.3) 的多线程应用程序
我遇到了似乎很普遍的数据库锁定错误。 我想知道在我的情况下如何避免它。
让我描述一下我正在构建的内容。抱歉,没有代码,它太大太复杂了。
我有大约 8 个线程同时访问数据库。这些线程中的任何一个都可以同时读取或写入。
数据库中表中的每一行都有一个指向资源的文件路径+与该资源相关的其他属性。
需要注意的 3 个字段是 reader、status 和 del。
每次线程从资源中读取时,Readers 都会增加,但前提是 status > 0 且 del = 0。
所以我有一些 SQL
UPDATE resource set readers=readers+1 where id=? AND del=0 AND status>0
之后,我检查更新的行数。它应该只有 1。 之后,我尝试通过选择读回该行。即使失败了我也会这样做 更新,因为我需要知道失败的原因。
我尝试将更新和选择都包含在事务中,但这没有帮助。 我已经检查过我是否也在对我的陈述进行敲定。
现在,我认为 sqlite 默认会序列化。我尝试了几种打开模式,但仍然出现相同的错误。
在你问之前,不,我不打算去 mysql。我绝对需要零配置。
有人可以提供一些关于如何避免此类问题的指示吗?我应该将读者锁移出数据库吗?如果我这样做,我应该用什么机制替换它?我在 C++ 下使用 Linux,并且提供了 boost 库。
编辑: 有趣的是,在我更新调用后添加 COMMIT 显着改善了情况。
【问题讨论】:
-
提交更频繁允许对数据库文件进行更细粒度的独占锁,这将减少读者等待表解锁的时间。这是以增加日志文件开销为代价的。查看sqlite.org/lockingv3.html#writing 了解更多信息。