我可以从多个连接并发地读写 SQLite 数据库吗?

我有一个由两个进程使用的 SQLite 数据库。我想知道,在使用最新版本的 SQLite 时,当一个进程(连接)启动一个要写入数据库的事务时,另一个进程是否能够同时从数据库读取数据?

97136 次浏览

我从各种渠道收集信息,大部分来自 sqlite.org,然后把它们放在一起:

首先,默认情况下,多个进程可以同时打开相同的 SQLite 数据库,并且可以并行地满足多个读访问。

在进行写操作时,对数据库的一次写操作会短时间锁定数据库,根本不能访问数据库文件,甚至不能进行读操作。

Beginning with version 3.7.0, a new “Write Ahead Logging” (WAL) option is available, in which reading and writing can proceed concurrently.

默认情况下,不启用 WAL。要打开 WAL,请参考 SQLite 文档。

SQLite3明确允许 多重连接:

(5)可以多个应用程序或多个相同的实例 应用程序同时访问单个数据库文件?

多个进程可以同时打开相同的数据库。 多个进程可以同时执行一个 SELECT 中的任何时候都可以对数据库进行更改 time, however.

For sharing connections, use SQLite3共享缓存:

从3.3.0版开始,SQLite 包括一个特殊的“共享缓存” mode (默认情况下禁用)

In version 3.5.0, shared-cache mode was modified so that the same 缓存可以跨整个进程共享,而不只是在 一根线。

5.0启用共享缓存模式

Shared-cache mode is enabled on a per-process basis. Using the C 接口,下面的 API 可用于全局启用或禁用 共享缓存模式:

Int sqlite3 _ enable _ share _ cache (int) ;

每个调用 sqlite3 _ enable _ share _ cache ()都会影响后续数据库 使用 sqlite3 _ open ()、 sqlite3 _ open16()或 Sqlite3 _ open _ v2() 每次对 sqlite3 _ enable _ share _ cache ()的调用都会覆盖所有 同一进程中的以前调用。

我和你的代码架构很相似。我使用了一个单独的 SQLite 数据库,该数据库处理从 A 读取的数据,而进程 B 根据事件并发地写入该数据库。(在 python 3.10.2中使用最新的 sqlite3版本)。进程 B 不断地更新数据库,而进程 A 则从数据库中读取数据以检查数据。我的问题是它在调试模式下工作,而不是在“发布”模式下。

为了解决我的特殊问题,我使用了 提前写日志,这在以前的答案中有所参考。在进程 B (写模式)中创建数据库之后,我添加了以下代码行:

其中 cur 是通过建立连接创建的游标对象。

这将日志设置为 wal 模式,该模式允许对多个读操作进行并发访问(但只能进行一次写操作)。在进程 A 中,我正在读取数据,在连接到同一个数据库之前,我包括:

time.sleep(0.5)

在连接到同一个数据库之前设置一个睡眠计时器修复了我的问题,因为它不能在“发布”模式下工作。

在我的例子中: 我不需要手动设置任何检查点、锁或事务。但是,您的用例可能与我的不同,因此最有可能需要进行研究。尽管如此,我还是希望这篇文章能帮助大家节省一些时间!