在提交数据的SQLite连接之间是否存在传播延迟

Is there a propagation delay between SQLite connections for committed data?

本文关键字:是否 存在 传播 延迟 之间 连接 提交 数据 SQLite      更新时间:2023-10-16

我们有一个OSX(10.10.4)上的c++应用程序在MacBook Pro(无虚拟机)上本机运行,使用SQLite 3.7.7.1(旧的,我意识到),我看到以下行为:

  1. app的线程1连接到file1.db(在Journaled HFS+分区上),创建一个保存点,将行插入到表1,然后释放保存点

  2. 同一应用程序的线程2连接到file2.db,并且先前在同一连接中附加了file1.db。它现在尝试插入到file2中。

If 1 &在1秒内,我们看到在步骤1中插入的行没有插入到表2中。但是如果我们在步骤1和步骤1之间等一秒钟2、我们总是看到插入的行。第2步肯定发生在第1步提交之后,因为我们正在记录语句并可以观察到它。

我们在默认的journal_mode (delete)下运行

在journal_mode=delete时,同一应用程序共享的连接之间是否存在某种传播延迟?管理隔离级别的规则(https://www.sqlite.org/isolation.html)并没有明确禁止它。

问题解决:

这种行为的根源是由于我们对保存点如何工作的误解。具体来说,回滚一个保存点并不会删除该保存点,因此在"rollback TO"命令之后对连接的后续操作仍然在原始保存点的事务中。

在我们的示例中,在步骤1中描述的保存点之前有一个保存点,该保存点已经回滚,因此线程1在其释放的保存点内的工作对其他连接仍然不可见。线程1中使用与之前回滚的保存点同名的保存点的后续操作被释放,它最终提交了线程1中的数据,这就是为什么我们看到数据稍后出现在线程2的连接中。

因为我们使用一个简单的保存点类作为堆栈创建的保护对象,它跟踪我们在创建保存点时嵌套了多少个级别(这就是保存点名称被重用的方式),解决方案是简单地确保最外层创建的保存点(即,在该连接上当前没有其他保存点活动时创建的保存点)使用"BEGIN TRANSACTION"/"COMMIT"/"ROLLBACK",并且在该连接中创建的所有保存点使用"Savepoint SP_1"。"SAVEPOINT_SP2"等。