代码之家  ›  专栏  ›  技术社区  ›  hookenz

避免sqlite3数据库被锁定

  •  6
  • hookenz  · 技术社区  · 15 年前

    我有一个使用sqlite(3.7.3)的多线程应用程序

    我遇到了数据库锁定错误,这似乎非常普遍。 我想知道在我的情况下如何避免它。

    让我描述一下我正在建设什么。抱歉,没有代码,太大太复杂了。

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

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

    3个值得注意的字段是readers、status和del。

    每次线程从资源中读取时,读卡器都会增加,但前提是status>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 回复  |  直到 15 年前
        1
  •  4
  •   ravenspoint    15 年前

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

    int sqlite3_busy_timeout(sqlite3*, int ms);
    

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

        2
  •  2
  •   Berin Loritsch    15 年前

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

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

    显然,必须使用SQLite_THREADSAFE预处理器选项设置为1来编译SQLite。他们确实有办法确定这是否是你的问题。

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