c# - 为什么 SQLite 仍然无法在序列化模式下从多个线程快速写入?
问题描述
我正在尝试使用多个线程非常快速地使用 EF Core 2.2(1000 行,延迟约 20 毫秒)将记录写入 SQLite。我收到此错误:
System.InvalidOperationException: '在前一个操作完成之前,在此上下文上启动了第二个操作。这通常是由使用相同 DbContext 实例的不同线程引起的,但不能保证实例成员是线程安全的。这也可能是由在客户端上评估嵌套查询引起的,如果是这种情况,请重写查询以避免嵌套调用。
我可以使用WAL (Write Ahead Logging)
哪个效果更好,但仍然会导致问题,如果我使用带有 WAL 的手动锁定,那么它可以工作,但我不喜欢拥有单独文件的不便,如果有,这些文件不会保存到主数据库崩溃。使用没有 WAL 的简单锁也可以,但一次最多冻结几秒钟。
为什么在使用此配置编译 SQLite 程序集时会发生此错误:
COMPILER=msvc-1700
DEFAULT_FOREIGN_KEYS
ENABLE_COLUMN_METADATA
ENABLE_FTS3_PARENTHESIS
ENABLE_FTS4
ENABLE_FTS5
ENABLE_JSON1
ENABLE_RTREE
THREADSAFE=1
THREADSAFE=1
表示根据https://www.sqlite.org/threadsafe.html进行序列化,这应该可以防止多个线程尝试使用相同的 DbContext 写入数据库时出现问题。
SQLITE_THREADSAFE=1) SQLite 库本身会序列化对数据库连接和prepared statements 的访问,以便应用程序可以自由地同时在不同线程中使用相同的数据库连接或相同的prepared statement。
我想了解为什么会这样。
解决方案
推荐阅读
- java - selenium .getElementsBy() 索引 0 与单个 .getElementBy()
- mariadb - Debian 下的 MariaDB 安全脚本
- android - 如何将应用程序包 (.aab) 上传到我的私人 Nexus 存储库?
- c# - RTF 通过 RichTextBox 转 HTML,如何设置正确的字体大小?
- javascript - 为什么无法在数组中获取输入值复选框?
- haskell - Haskell中的对称关系
- javascript - 创建上传到 Onedrive 按钮
- python-3.8 - IndexError:列表索引超出范围。附加到列表
- azure - 在 azure 中我们可以更新 profile.ps1 文件功能应用程序吗?
- android - Android:无法更新 RecyclerView