SQLite 中的 SAVEPOINT 机制

Pro*_*zzz 5 sqlite transactions savepoints

我正在尝试了解 SQLite 中的保存点和事务。我在表/数据库上有以下命令,我正在使用保存点。

SAVEPOINT aaa;
RELEASE aaa;
BEGIN;
Run Code Online (Sandbox Code Playgroud)

现在,如果我一次执行上述所有语句,它会抛出一个错误,说A transaction cannot be started inside another transaction. 如果我一次运行一个,它工作正常。如果我运行前两个 Savepoint 和 release 命令并尝试通过执行Begin. 它再次抛出与以前相同的错误。

这里的链接说

如果 SAVEPOINT 命令在 SQLite 处于自动提交模式时(即在事务之外)发出,则将启动标准自动提交 BEGIN DEFERRED TRANSACTION。但是,与大多数命令不同,自动提交事务在 SAVEPOINT 命令返回后不会自动提交,使系统处于打开的事务中。自动事务将保持活动状态,直到原始保存点被释放,或者外部事务被显式提交或回滚。`

那么,Release Savepoint 命令之后是否一定需要 Commit 或 Rollback 命令呢?不release命令提交并允许我们使用BEGIN?

Dav*_*tti -2

SAVEPOINT aaa; RELEASE aaa; BEGIN;

被 sqlite 解释为

BEGIN DEFERRED TRANSACTION; SAVEPOINT aaa; // Create a transaction, and mark current db state as savepoint "aaa" [1] RELEASE aaa; // Remove all db changes made since savepoint "aaa", but keep on executing the transaction BEGIN; // Create another transaction, while there is already a transaction. This will FAIL because there cannot be 2 transactions executed simultaneously

以下内容就可以了:

BEGIN; SAVEPOINT "aaa"; RELEASE "aaa"; COMMIT; BEGIN;

[1] https://sqlite.org/lang_savepoint.html

  • 根据您发布的文档链接,释放最外层保存点应该提交:“如果 RELEASE 命令释放最外层保存点,从而使事务堆栈变空,则 RELEASE 与 COMMIT 相同。”。它还取决于当前的自动提交值 - 根据 https://www.safaribooksonline.com/library/view/using-sqlite/9781449394592/ch04s07.html “...但是,与大多数命令不同,自动提交事务不会自动在 SAVEPOINT 命令返回后提交,使系统处于开放事务中......” (5认同)
  • 链接的文档说“当 SAVEPOINT 是最外层的保存点并且不在 BEGIN...COMMIT 内时,行为与 BEGIN DEFERRED TRANSACTION 相同。” 它说**与**相同,而不是“也”。你的解释不正确。正如 awattar 所评论的那样,没有 BEGIN TRANSACTION 启动的最外层 SAVEPOINT 将在匹配的 RELEASE 上提交。问题中描述的行为可能是由于第三方工具的错误/自动事务处理造成的。我在多个 sqlite 工具中观察到许多类似的问题。 (4认同)
  • 听听 @awattar 和 CPerkins 怎么说。这个“被 sqlite 解释为”你的答案的一部分是错误的。它给本已复杂的话题增添了不确定性。请重新表述您的答案以避免出现这种情况。“就好了”部分很好:) (4认同)