SQLite多进程访问

时间:2010-05-05 17:57:53

标签: c# multithreading sqlite encryption

我们在多进程和多线程应用程序中使用SQLite。 SQLite数据库文件使用嵌入式SQLite加密进行加密。 FAQ表示SQLite应该能够使用锁机制管理多进程访问。 我们遇到了一个奇怪的问题: 当许多线程访问同一个数据库文件时,有时会发生约束违规,更具体地说 - 具有唯一约束的字段在调用“insert或replace”语句后获得重复值。 它现在经常发生,我们正在使用加密。在我们开始使用SQLite加密之前,我们没有注意到这种行为。 这有什么具体的已知问题吗?

3 个答案:

答案 0 :(得分:9)

虽然SQLite是“线程安全的”,但您仍然无法同时修改数据库:

  

然后每个线程继续插入一个   记录数量,比方说1000   你会遇到的问题是   以下:一个线程将获得控制权   通过设置锁定在数据库上   文件。这很好,但其余的   线程将继续失败   对于每次尝试INSERT而   锁是活跃的。   (reference

一次只允许一个线程修改数据库,但是您可以有多个尝试的线程来修改数据库。

如果您想避免失败时锁定问题,可以检查SQLITE_BUSY标志:

  

测试SQLITE_BUSY,我没有   最初做的。这是一些伪代码   说明一个解决方案:

  while (continueTrying) {
    retval = sqlite_exec(db, sqlQuery, callback, 0, &msg);
    switch (retval) {
      case SQLITE_BUSY:
        Log("[%s] SQLITE_BUSY: sleeping fow a while...", threadName);
        sleep a bit... (use something like sleep(), for example)
        break;
      case SQLITE_OK:
        continueTrying = NO; // We're done
        break;
      default:
        Log("[%s] Can't execute \"%s\": %s\n", threadName, sqlQuery, msg);
        continueTrying = NO;
        break;
    }
  }

  return retval;

same reference

我敢打赌,你的约束违规与多线程无关,所以请你发布你得到的实际约束违规(或者符合www.sscce.org的例子)。

答案 1 :(得分:2)

感谢您的所有评论!

(提到我们正在使用System.Data.SQLite .Net库)

与此同时,我们进行了一些测试,结果是

===============

我们已经构建了一个执行以下操作的测试器: - 创建一个包含许多字段的表。其中一个字段--nvarchar(255) - 具有唯一索引:“在表上创建唯一索引IX_MyKey(MyKey)” - 同时启动许多识别过程(25) - 每个进程都有一个Key(字符串代表1-25) - 每个进程都有一个(主)线程在循环中执行以下操作30秒:

  

读取MyKey = @ MyKey的记录(过程的关键)   获取数字字段的值   将'value + 1'写回同一记录的同一字段“insert or replace ... where MyKey = @ MyKey”

===============

  • 当我们使用没有加密的System.Data.SQLite库完成上述操作时 - 一切都按预期工作(包括在进程数量增加时减慢对数据库的访问的锁)

    < / LI>
  • 当我们使用加密(通过设置数据库的密码)时,索引唯一约束被“破坏” - 出现具有相同MyKey值的记录

===============

因此接缝问题与加密有某种关系......

答案 2 :(得分:0)

确保您没有跨线程共享连接 - 每个线程都应该建立自己的连接。并确保将查询包装在事务中。

我使用开源的System.Data.Sqlite(http://sqlite.phxsoftware.com/)ADO.Net包装器,只要您不跨线程共享连接,它就是线程安全的。它也很容易加密数据库,如下所述:http://sqlite.phxsoftware.com/forums/t/130.aspx(只需设置密码属性)。在他的论坛中搜索他如何专门使用Microsoft Crypto API进行加密,以及有关线程安全的详细信息。