SQL 事务实战:使用保存点撤销一段任务更新
在同一事务中创建保存点,撤销部分插入并提交其他修改,理解回滚边界、连接生命周期和最终查询结果。
本节目标
在同一事务中创建保存点,撤销部分插入并提交其他修改,理解回滚边界、连接生命周期和最终查询结果。
环境与运行方法
使用 SQLite 3 验证本组 SQL。将完整示例保存为 lesson.sql,执行 sqlite3 :memory: < lesson.sql。每次运行都是独立内存数据库,不会覆盖已有数据;其他数据库的类型和事务细节可能不同。
核心思路
事务将多条操作组合为一个提交单元,保存点允许撤销其中一段。本例先写入保留记录,再建立保存点,写入试验记录后回滚到保存点,最后提交外层事务。
完整示例
CREATE TABLE tasks(id INTEGER PRIMARY KEY, title TEXT NOT NULL);
BEGIN;
INSERT INTO tasks VALUES(1,'keep');
SAVEPOINT trial;
INSERT INTO tasks VALUES(2,'discard');
ROLLBACK TO trial;
RELEASE trial;
INSERT INTO tasks VALUES(3,'finish');
COMMIT;
SELECT id,title FROM tasks ORDER BY id;预期输出
1|keep
3|finish逐步理解
ROLLBACK TO 只撤销保存点之后的修改,不会把之前的 keep 删除。RELEASE 释放保存点,外层事务仍需 COMMIT。之后插入 finish,并一起提交,因此最终只有编号 1 和 3。
本例主动回滚演示边界,并没有模拟某个约束异常自动触发回滚。应用程序遇到数据库错误时应按驱动和数据库语义明确处理事务。不要假设任何错误都会自动清除整批操作。
常见问题与边界
- RELEASE 保存点不一定等于提交外层事务。
- 事务控制通常属于同一个连接。
- 内存数据库关闭后消失,本例不演示持久化备份。
动手练习
去掉 ROLLBACK TO trial,再运行一次。
参考答案
三条记录都会保留。恢复回滚语句后,编号 2 消失。验证使用全新内存库,避免旧数据影响对事务行为的判断。
文章回复
0 条公开回复