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

时间:2015-08-28 20:51:06

标签: c++ macos sqlite

我们在OSX(10.10.4)上有一个C ++应用程序,在MacBook Pro(无VM)上本地运行,使用SQLite 3.7.7.1(旧的,我意识到),并且我看到以下行为:< / p>

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

  2. 同一应用程序的线程2与file2.db有连接,并且先前已在同一连接中附加了file1.db。它现在尝试通过从file1.table1中选择插入到file2.table2中。

  3. 如果1&amp; 2发生在一起(在1秒内),我们看到在步骤1中插入的​​行没有插入到table2中。但如果我们在第1步和第1步之间等待1秒2,我们总是看到插入的行。在步骤1提交之后肯定会发生第2步,因为我们正在记录语句并且可以观察它。

    我们正在默认的journal_mode(删除)中运行。

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

1 个答案:

答案 0 :(得分:0)

解决问题:

这种行为的根源是由于我们对保存点的工作方式存在误解。具体来说,回滚保存点不会删除保存点,因此在&#34; ROLLBACK TO&#34;之后对连接进行后续操作。命令仍在原始保存点的事务中。

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

由于我们使用简单的Savepoint类作为堆栈创建的保护对象,它跟踪我们在创建保存点时嵌套的级别(这是保存点名称被重用的方式),解决方案只是为了确保创建的最外面的保存点(即,当该连接上当前没有其他保存点时创建的保存点)使用&#34; BEGIN TRANSACTION&#34; /&#34; COMMIT&#34; /& #34; ROLLBACK&#34;并且在那个中创建的所有保存点都使用&#34; SAVEPOINT SP_1&#34;,&#34; SAVEPOINT_SP2&#34;等