首页 > 解决方案 > 为什么 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。

我想了解为什么会这样。

标签: c#multithreadingsqlitelockingentity-framework-core

解决方案


推荐阅读