SAVEPOINT

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

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

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

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

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

    ERROR 1305 (42000): SAVEPOINT identifier does not exist

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

示例

创建表 t1

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

开始当前事务:

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

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

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

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

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

释放保存点 sp2

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

回滚至保存点 sp1

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

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

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

MySQL 兼容性

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

另请参阅