SAVEPOINT

SAVEPOINT 是 TiDB 从 v6.2.0 开始支持的特性,语法如下:

  1. SAVEPOINT identifier
  2. ROLLBACK TO [SAVEPOINT] identifier
  3. RELEASE SAVEPOINT identifier

SAVEPOINT - 图1

警告

SAVEPOINT 特性不支持与 TiDB Binlog 一起使用,也不支持在关闭 tidb_constraint_check_in_place_pessimistic 的悲观事务中使用。

  • SAVEPOINT 语句用于在当前事务中,设置一个指定名字保存点。如果已经存在相同名字的保存点,就删除已有的保存点并设置新的保存点。

  • ROLLBACK TO SAVEPOINT 语句将事务回滚到指定名称的事务保存点,而不终止该事务。当前事务在设置保存点后,对表数据所做的修改将在回滚中撤销,且删除事务保存点之后的所有保存点。在悲观事务中,对于已经持有的悲观锁不会回滚,而是在事务结束时才释放。

    如果 ROLLBACK TO SAVEPOINT 语句中指定名称的保存点不存在,则会返回以下错误信息:

    1. ERROR 1305 (42000): SAVEPOINT identifier does not exist
  • RELEASE SAVEPOINT 语句将从当前事务中删除指定名称及之后的所有保存点,而不会提交或回滚当前事务。如果指定名称的保存点不存在,则会返回以下错误信息:

    1. ERROR 1305 (42000): SAVEPOINT identifier does not exist

    当事务提交或者回滚后,事务中所有保存点都会被删除。

示例

创建表 t1

  1. CREATE TABLE t1 (a int NOT NULL PRIMARY KEY);
  1. Query OK, 0 rows affected (0.12 sec)

开始当前事务:

  1. BEGIN;
  1. Query OK, 0 rows affected (0.00 sec)

向表中插入数据并设置保存点 sp1

  1. INSERT INTO t1 VALUES (1);
  1. Query OK, 1 row affected (0.00 sec)
  1. SAVEPOINT sp1;
  1. Query OK, 0 rows affected (0.01 sec)

向表中再次插入数据并设置保存点 sp2

  1. INSERT INTO t1 VALUES (2);
  1. Query OK, 1 row affected (0.00 sec)
  1. SAVEPOINT sp2;
  1. Query OK, 0 rows affected (0.01 sec)

释放保存点 sp2

  1. RELEASE SAVEPOINT sp2;
  1. Query OK, 0 rows affected (0.01 sec)

回滚至保存点 sp1

  1. ROLLBACK TO SAVEPOINT sp1;
  1. Query OK, 0 rows affected (0.01 sec)

提交事务并查询表格,发现表中仅有 sp1 前插入的数据:

  1. COMMIT;
  1. Query OK, 0 rows affected (0.01 sec)
  1. SELECT * FROM t1;
  1. +---+
  2. | a |
  3. +---+
  4. | 1 |
  5. +---+
  6. 1 row in set

MySQL 兼容性

使用 ROLLBACK TO SAVEPOINT 语句将事物回滚到指定保存点时,MySQL 会释放该保存点之后才持有的锁,但在 TiDB 悲观事务中,不会立即释放该保存点之后才持有的锁,而是等到事务提交或者回滚时,才释放全部持有的锁。

另请参阅