⚡ 编程实验室🏗️ HTML🎨 CSS⚡ JavaScript🐍 Python🗄️ SQL☕ Java⚛️ React💚 Vue🟢 Node.js⚙️ C语言🐘 PHP🐹 Go🔷 TypeScript🐬 MySQL🔧 C++🎯 C#🦀 Rust🅱️ Bootstrap💡 jQuery🎸 Django🍃 MongoDB👗 Sass🎪 Kotlin📊 R语言📋 XML📊 Excel🐘 PostgreSQL🐳 Docker🅰️ Angular🎮 游戏🏠 网站首页

SQL 保存点

学习SAVEPOINT · 难度:高级 · +15XP

SQL 保存点(SAVEPOINT)

在事务处理中,有时你只想回滚部分操作而不是整个事务。比如在一个包含 10 个步骤的事务中,第 7 步出错了,你只想撤销第 5-7 步,保留前 4 步的成果。SQL 的 SAVEPOINT(保存点)机制就是为这种场景设计的,它允许你在事务中设置标记点,之后可以精确回滚到指定标记而非事务开头。

SAVEPOINT 基本语法

-- 创建保存点
SAVEPOINT 保存点名称;

-- 回滚到指定保存点 ROLLBACK TO 保存点名称;

-- 释放保存点(某些数据库支持) RELEASE SAVEPOINT 保存点名称;

完整示例

以下示例模拟一个银行转账场景,展示保存点的实际用法:

-- 开始事务
BEGIN;

-- 步骤1:从账户A扣款100元 UPDATE accounts SET balance = balance - 100 WHERE id = 1; -- 设置保存点A_deducted SAVEPOINT A_deducted;

-- 步骤2:向账户B加款100元 UPDATE accounts SET balance = balance + 100 WHERE id = 2; -- 设置保存点B_added SAVEPOINT B_added;

-- 步骤3:记录转账日志(假设这里出错了) INSERT INTO transfer_log(account_from, account_to, amount) VALUES (1, 2, 100);

-- 发现日志表不存在,回滚到B_added ROLLBACK TO B_added;

-- 重新记录日志(或跳过) INSERT INTO transfer_log(account_from, account_to, amount) VALUES (1, 2, 100);

-- 全部完成,提交 COMMIT;

SAVEPOINT 的重要规则

规则说明
保存点在事务内SAVEPOINT 只能在事务(BEGIN/START TRANSACTION)内部使用
回滚后保存点不删除ROLLBACK TO 某保存点后,该保存点仍然存在,可以再次回滚到它
回滚删除后续点回滚到前面的保存点时,之后创建的保存点会被删除
COMMIT 清除所有提交事务后,所有保存点自动释放
同名覆盖创建同名保存点会覆盖之前的同名保存点

适用场景

  1. 批量数据处理:处理多条记录时,每条记录设置保存点,出错只回滚当前记录
  2. 复杂业务流程:多步骤操作中,每步完成后设置保存点
  3. 测试与调试:在 SQL 脚本中分段设置保存点,方便分段回滚测试
  4. 嵌套事务模拟:在 MySQL(不原生支持嵌套事务)中模拟嵌套事务效果

数据库兼容性

SAVEPOINT 是 SQL 标准,主流数据库都支持:MySQL、PostgreSQL、Oracle、SQLite、SQL Server。但语法细节可能略有差异。

实战任务

  1. 在一个事务中插入 3 条学生记录,每条插入后设置保存点
  2. 回滚到第 2 个保存点,观察最终提交后表中保留了几条数据
  3. 尝试在事务外使用 SAVEPOINT,观察报错信息
Ctrl+Enter
🚀 升级VIP
解锁全部课程+AI助手

🏆 学习排行

加载中...

📊 统计

📖 146 篇
0 完成
🔥 0