功能描述
保存点(Savepoint)是事务内的一个标记点,允许在事务执行过程中设置回滚点,实现部分回滚而不影响整个事务。
语法
设置保存点
在当前事务中创建指定名称的保存点。
如果同名保存点已存在,则删除原保存点并创建新的保存点。
SAVEPOINT savepoint_name;
回滚到保存点
将事务回滚到指定保存点,不终止事务。
回滚后,保存点之后的所有数据修改将被撤销。
后续保存点会被自动删除。
ROLLBACK TO SAVEPOINT savepoint_name;
释放保存点
删除指定保存点及之后创建的所有保存点。不提交或回滚事务。
RELEASE SAVEPOINT savepoint_name;
参数说明
参数 | 是否必选 | 说明 |
savepoint_name | 是 | 保存点的唯一名称标识,支持大小写英文字母、数字。 |
注意事项
回滚或释放不存在的保存点时,会返回错误
ERROR 1305 (42000): SAVEPOINT does not exist。事务提交或回滚后,所有保存点自动清除。
保存点名称在同一事务内必须唯一。
示例
1. 准备环境。
-- 创建测试表CREATE TABLE account (id INT PRIMARY KEY,name VARCHAR(50),balance DECIMAL(10,2));-- 插入测试数据INSERT INTO account VALUES (1, 'Alice', 1000.00);INSERT INTO account VALUES (2, 'Bob', 500.00);
2. 事务操作流程。
-- 开始事务BEGIN;-- 查看初始状态SELECT * FROM account WHERE id IN (1,2);-- Alice向Bob转账100元UPDATE account SET balance = balance - 100 WHERE id = 1;SELECT * FROM account WHERE id IN (1,2);-- 设置保存点sp1SAVEPOINT sp1;-- Bob收到100元UPDATE account SET balance = balance + 100 WHERE id = 2;SELECT * FROM account WHERE id IN (1,2);-- 设置保存点sp2SAVEPOINT sp2;-- 再次转账50元UPDATE account SET balance = balance - 50 WHERE id = 1;UPDATE account SET balance = balance + 50 WHERE id = 2;SELECT * FROM account WHERE id IN (1,2);-- 设置保存点sp3SAVEPOINT sp3;-- 回滚到sp2保存点(撤销第二次转账)ROLLBACK TO SAVEPOINT sp2;SELECT * FROM account WHERE id IN (1,2);-- 释放sp1保存点(删除sp1及之后的所有保存点)RELEASE SAVEPOINT sp1;-- 尝试回滚到sp3会失败(因为sp3已被删除)-- ROLLBACK TO SAVEPOINT sp3; -- 这行会报错-- 提交事务COMMIT;
3. 验证结果。
-- 查询最终余额SELECT * FROM account;
预期结果:
+----+-------+---------+| id | name | balance |+----+-------+---------+| 1 | Alice | 900.00 || 2 | Bob | 600.00 |+----+-------+---------+
执行过程状态变化:
操作步骤 | Alice 余额 | Bob 余额 | 说明 |
初始状态 | 1000.00 | 500.00 | 事务开始前 |
第一次转账 | 900.00 | 500.00 | Alice 转出100元 |
设置 sp1 后 | 900.00 | 600.00 | Bob 收到100元 |
设置 sp2 后 | 850.00 | 650.00 | 再次转账50元 |
回滚到 sp2 | 900.00 | 600.00 | 撤销第二次转账 |
最终提交 | 900.00 | 600.00 | 事务完成 |