为什么释放没有外部事务的保存点不会保存更改?

时间:2019-04-25 18:45:11

标签: sqlite

根据SQLite3文档发布的顶级保存点(不与外部事务包装在一起),提交其更改。但实际上这不会发生。有什么问题吗?

更新

我发现这是在回滚上一个保存点之后发生的:

#include <sqlite3.h>
#include <stdio.h>

int main() {
  sqlite3* db;
  if (sqlite3_open("/Users/ababo/Desktop/test.sqlite3", &db) != SQLITE_OK) {
    fprintf(stderr, "failed to create db: %s\n", sqlite3_errmsg(db));
    return 1;
  }

  const char* sql = "SAVEPOINT sp";
  if (sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK) {
    fprintf(stderr, "failed to create savepoint: %s\n", sqlite3_errmsg(db));
    return 1;
  }

  sql = "ROLLBACK TO sp";
  if (sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK) {
    fprintf(stderr, "failed to rollback savepoint: %s\n", sqlite3_errmsg(db));
    return 1;
  }

  sql = "SAVEPOINT sp";
  if (sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK) {
    fprintf(stderr, "failed to create savepoint again: %s\n",
            sqlite3_errmsg(db));
    return 1;
  }

  sql = "CREATE table t(f int)";
  if (sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK) {
    fprintf(stderr, "failed to create table: %s\n", sqlite3_errmsg(db));
    return 1;
  }

  sql = "RELEASE sp";
  if (sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK) {
    fprintf(stderr, "failed to release savepoint: %s\n", sqlite3_errmsg(db));
    return 1;
  }

  return 0;
}

更新2

据我了解,问题在于RELEASE sp不会从事务堆栈中删除保存点,因此下一个SAVEPOINT sp会推送下一个保存点。有没有办法在回滚时删除保存点?

1 个答案:

答案 0 :(得分:0)

RELEASE命令清除第二个sp保存点的事务堆栈。但是,外部(第一个)保存点仍在事务堆栈上,因为ROLLBACK TO命令不会清除目标保存点。如果您使用了ROLLBACK(没有TO子句),那么将清除第一个保存点。

有关更多详细信息,请参见SQLite docs