MySQL 基础 ———— SAVEPOINT 的应用

引言

savepoint 关键字用于在数据库事务中设置一个存储点,在一个较长的事务中暂存数据,如果在事务末尾执行回滚,可选择性的回滚到 savepoint 设置的暂存点。

本文承接上一篇博客《MySQL 基础 ————事务与隔离级别总结》,进一步探讨事务在实际生产中的重要场景——回滚。

一、SAVEPOINT 语法

SAVEPOINT identifier
ROLLBACK [WORK] TO [SAVEPOINT] identifier
RELEASE SAVEPOINT identifier

数据库的 InnoDB 存储引擎(一般情况下都是指此引擎,该引擎是MySQL默认存储引擎,因为另一个比较常见的存储引擎MyISAM不支持事务)支持的 SAVEPOINT 语句,包括上述三种。

SAVEPOINT 通过自定义的名称设置一个存储点,如果当前事务已经有了一个同名的 SAVEPOINT ,那么旧的将会被替代。

ROLLBACK TO SAVEPOINT 子句可以将当前事务回退到自定义的存储点位置,而不会结束事务,InnoDB 不会释放内存中的行锁(对于新插入的行,锁信息是由存储在行中的事务ID携带,而不会单独存储在内存中,那么对于这类锁,是会被释放的),存储点之后语句都会撤销执行,包括新设置的存储点,也同样会被删除。

RELEASE SAVEPOINT 子句,会从当前的事务 SAVEPOINT 集合中,移除指定名称的 SAVEPOINT 。

另外,执行 COMMIT 或 ROLLBACK (未指定 SAVEPOINT)都会清空当前事务的所有 SAVEPOINT。

二、演示

员工表:

MySQL 基础 ———— SAVEPOINT 的应用_第1张图片

操作过程是,开启事务,然后执行两条更新语句,第一条更新 6 号员工的工资,然后设置一个 SAVEPOINT ,第二条更新 9 号员工的工资,执行完成后,回滚到 SAVEPOINT ,然后 COMMIT ,查看6 号 和 9 号员工的工资各有什么变化。

1、开启事务:

SET autocommit = 0;

2、执行更新 6 号员工工资的语句: 

UPDATE emp SET salary = 4000 WHERE emp_id = 6;

MySQL 基础 ———— SAVEPOINT 的应用_第2张图片 

3、执行 SAVEPOINT:

SAVEPOINT id_6_updated;

4、再执行第二条语句,更新 9 号员工的工资:

UPDATE emp SET salary = 6000 WHERE emp_id = 9;

MySQL 基础 ———— SAVEPOINT 的应用_第3张图片

5、然后,回滚到 SAVEPOINT id_6_updated:

ROLLBACK TO SAVEPOINT id_6_updated;

6、提交更新:

COMMIT;

7、查看最后的更新结果:

MySQL 基础 ———— SAVEPOINT 的应用_第4张图片

可以看到, 6 号员工的工资成功被修改,而 9 号员工的工资虽然执行了更新,但是因为回滚到了执行语句之前的 SAVEPOINT 而没有被更新。

 

你可能感兴趣的:(数据库与SQL语句)