我正在运行多个线程,每个线程都尝试对一个 SQLite 数据库执行 INSERTS。每个线程都创建自己与数据库的连接。他们各自创建一个命令,打开一个事务执行一些 INSERTS,然后关闭事务。似乎尝试任何操作的第二个线程得到以下 SQLiteException:数据库文件已锁定。我尝试从事务中解开 INSERTS 并缩小每个提交中包含的 INSERTS 的范围,但没有实际效果;对 db 文件的后续访问会引发相同的异常。
有什么想法吗?我被难住了,我不知道下一步该往哪里看……
我正在运行多个线程,每个线程都尝试对一个 SQLite 数据库执行 INSERTS。每个线程都创建自己与数据库的连接。他们各自创建一个命令,打开一个事务执行一些 INSERTS,然后关闭事务。似乎尝试任何操作的第二个线程得到以下 SQLiteException:数据库文件已锁定。我尝试从事务中解开 INSERTS 并缩小每个提交中包含的 INSERTS 的范围,但没有实际效果;对 db 文件的后续访问会引发相同的异常。
有什么想法吗?我被难住了,我不知道下一步该往哪里看……
更新您的插入代码,以便如果遇到指示数据库锁定的异常,它会稍等片刻,然后重试。每次以随机增量增加等待时间(“随机退避”算法)。这应该允许线程各自获取全局写锁。性能会很差,但代码无需重大修改即可工作。
但是,SQLite 不适合高并发修改。您有两个永久解决方案:
要检查的两件事:
1) 确认您的 SQLite 版本是使用 THREAD 支持编译的
2) 确认您没有打开数据库 EXCLUSIVE
我不是在 C# 中执行此操作,而是在 Android 中执行此操作,但我通过在包装类的整个生命周期内始终在拥有它的包装类中打开 sqlite 数据库来解决这个“数据库已锁定”错误。然后在这个类中完成的每个插入都可以在它自己的线程中(因为,取决于你的数据存储情况,sd 卡与设备内存等,数据库写入可能需要很长时间),我什至尝试限制它,大约一次插入十几个线程,每个线程都处理得很好,因为插入方法不必担心打开/关闭数据库。
我不确定持久性数据库生命周期是否被认为是好的风格(在大多数情况下它可能被认为是不好的),但现在它工作得很好。