自动回滚多条语句的隐式事务?

时间:2019-04-16 19:30:56

标签: sqlite

当多个语句一起提交时,用分号(;分隔但在同一字符串中)且不包装在显式事务中,则仅创建单个隐式事务或创建隐式事务对于每个语句分别?此外,如果后面的一条语句失败并执行了自动回滚,是否所有语句都回滚?

另外answer个几乎可以满足我的问题,但是官方文档中的措辞让我感到困惑。实际上,这似乎是重复的,但是我特别想知道有关多条语句的隐式事务。另一个答案没有明确解决这种特殊情况。

作为示例(从另一个问题中借用),以下内容作为单个字符串提交:

INSERT INTO a (x, y) VALUES (0, 0);
INSERT INTO b (x, y) VALUES (1, 2); -- line 3 error here, b doesn't have column x

documentation

  

最后查询完成后,将提交自动启动的事务。 (强调)

  

隐式事务(自动启动的事务,不是由BEGIN启动的事务)在 last 活动语句完成时自动提交。重置或完成其准备好的语句后,该语句结束。 (强调)

关键字最后对我而言意味着可能有多个语句。当然,如果为每个单独的语句启动了隐式事务,那么单独执行每个语句将是要执行的“最后”语句,但是在单独的语句的上下文中,它应该只说 the 语句强调上下文一次只能是一条语句。

或者准备好的语句和未准备好的SQL字符串之间有区别吗? (但是据我了解,即使调用应用程序未保留准备好的语句以供重用,所有语句也都是准备好的,所以我不确定这是否很重要。)

在所有语句成功的情况下,一次提交或多次提交的结果本质上是相同的,但是文档只提到单个失败的语句会自动回滚,而没有提及其他一起提交的语句

1 个答案:

答案 0 :(得分:1)

sqlite3_prepare接口在查询字符串中编译 first SQL语句。这些函数的pzTail参数返回一个指向查询字符串未使用部分开头的指针。

例如,如果在示例中使用多语句SQL字符串调用sqlite3_prepare,则第一条语句是唯一对所生成的 prepared语句有效的语句。 pzTail指针(如果提供)指向第二条语句的开头。直到您再次使用sqlite3_prepare指针调用pzTail时,第二条语句才被编译为准备好的语句。

因此,不,不会回滚多个语句。 SQLite引擎创建的每个隐式事务都包含一个准备好的语句。