当前位置:首页 > 文章列表 > 数据库 > MySQL > MySQL SAVEPOINT 回滚后哪些锁仍然保留

MySQL SAVEPOINT 回滚后哪些锁仍然保留

来源:17golang原创 2026-09-11 12:46:44 0浏览 收藏

很多人把 ROLLBACK TO SAVEPOINT 理解成“回到之前的状态,所以锁也回去了”。这个理解不完整:它主要撤销保存点之后的行修改,但当前事务仍然活着,InnoDB 也不会因此自动释放保存点后记录到内存中的行锁。只有提交或不带保存点的完整回滚,才会结束事务并清理这批事务资源。

官方资料:https://dev.mysql.com/doc/refman/8.4/en/savepoint.html

记住一句话:ROLLBACK TO SAVEPOINT 回滚的是数据修改,不等于回滚锁的生命周期。普通行锁可能继续持有;如果是保存点后新插入的行,锁信息随事务 ID 记录在行中,回滚时会通过 undo 释放,这是一个需要单独记住的例外。

ROLLBACK TO SAVEPOINT 到底回滚了什么

SAVEPOINT s1 在当前事务中设置一个命名位置。ROLLBACK TO SAVEPOINT s1 撤销从该位置之后发生的行修改,但不会提交、结束事务;比它更晚创建的保存点会被删除。RELEASE SAVEPOINT s1 只是删除保存点本身,也不提交、不回滚数据。

因此,下面四个动作不能混为一谈:

动作数据修改事务和锁
ROLLBACK TO s1撤销 s1 之后的修改事务继续,锁不按“保存点”自动清空
RELEASE SAVEPOINT s1不改变只移除保存点
COMMIT全部确认事务结束并释放事务锁
ROLLBACK全部撤销事务结束并释放事务锁

按索引访问时,锁为什么还在

InnoDB 的行级锁本质上锁的是索引记录。按唯一索引定位一行时,通常关注记录锁;范围扫描在默认的 REPEATABLE READ 下还可能涉及 next-key lock,也就是“索引记录锁 + 前面的间隙锁”。间隙锁的作用是阻止其他事务向索引间隙插入,并不等同于某一行数据。

这就解释了一个常见现象:A 先更新一行,设置保存点,再更新另一行;A 回滚到保存点后,第二次更新的数据恢复了,但 B 仍可能在尝试更新那条记录时等待。不要只看 SELECT 的结果判断锁是否释放,也要看事务是否仍未结束、访问走了哪个索引以及当前隔离级别。

保存点回滚与事务锁生命周期关系图
图1:数据修改可以沿保存点撤销,但事务边界与已持有的索引锁是另一条生命周期。

如果使用 READ COMMITTED,间隙锁和不匹配记录的释放规则会与默认隔离级别不同;这不是保存点改变了锁语义,而是隔离级别改变了加锁和释放策略。排查时必须把隔离级别、索引和 SQL 类型一起记录。

用两个会话复现锁的边界

准备一张 InnoDB 表,先确保示例数据存在:

CREATE TABLE orders (
  id BIGINT PRIMARY KEY,
  status VARCHAR(20) NOT NULL,
  amount DECIMAL(10, 2) NOT NULL,
  KEY idx_status (status)
) ENGINE=InnoDB;

INSERT INTO orders (id, status, amount)
VALUES (101, 'new', 39.90), (102, 'new', 59.90);

会话 A 先修改并回到保存点,再故意保持事务不结束:

START TRANSACTION;
-- 中文注释:第一处修改作为保存点之前的事务操作
UPDATE orders SET amount = amount + 10 WHERE id = 101;
SAVEPOINT s1;
-- 中文注释:第二处修改会被 ROLLBACK TO s1 撤销
UPDATE orders SET amount = amount + 20 WHERE id = 102;
ROLLBACK TO SAVEPOINT s1;
-- 中文注释:这里只回滚数据,事务仍然开放,先不要 COMMIT
SELECT id, amount FROM orders WHERE id IN (101, 102);

此时会话 A 看到 102 的金额恢复,但 A 仍持有事务资源。会话 B 可以执行:

START TRANSACTION;
-- 中文注释:尝试修改会话 A 访问过的记录,观察是否等待
UPDATE orders SET status = 'paid' WHERE id = 102;
-- 中文注释:若语句等待,说明不能用数据已回滚来推断锁已释放

实验结束后,在会话 A 执行 COMMIT 或完整 ROLLBACK,再观察会话 B。生产环境排障还应结合 SHOW ENGINE INNODB STATUS、Performance Schema 的锁等待信息和事务列表,确认等待者、阻塞者、索引名与锁类型。

工程上怎么安排保存点

保存点适合把一个较大的业务事务拆成可恢复的小段,例如批量处理时允许某一组失败后撤销,但它不适合替代事务边界。建议按以下原则使用:

  • 把事务尽量缩短,网络请求、人工确认和重试不要夹在持锁事务里。
  • 回滚到保存点后,要么继续完成并 COMMIT,要么走完整 ROLLBACK,不要把连接交还连接池后再决定。
  • 对范围更新、非唯一索引和默认隔离级别,额外考虑间隙锁造成的插入等待。
  • 在异常处理和超时路径里记录事务 ID、SQL、索引、隔离级别与最终结束动作。
保存点与索引记录锁边界关系图
图2:把修改、保存点、索引记录和事务结束边界分开记录,才能解释回滚后的阻塞。

常见疑问

回滚到保存点后还能继续执行 SQL 吗?可以。它不会结束当前事务,但更晚创建的保存点已不可用,需要按新的逻辑继续或重新设置保存点。

RELEASE SAVEPOINT 能释放锁吗?不能把它当作解锁命令。它只移除保存点;需要结束事务时使用 COMMIT 或不带保存点的 ROLLBACK

看到数据恢复,为什么另一个会话还在等?因为数据版本和锁资源是两条不同的生命周期。先确认阻塞事务是否结束,再确认索引访问和隔离级别,最后用锁监控核对具体对象。

总结

ROLLBACK TO SAVEPOINT 的核心价值是局部撤销,不是局部解锁。普通保存点后的行锁不要假设会立即释放;新插入行的锁有 undo 释放例外;间隙锁和 next-key lock 还受索引与隔离级别影响。把保存点当作数据恢复工具,把提交或完整回滚当作事务收尾动作,才能避免“数据看起来没问题、请求却持续阻塞”的错觉。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Go bytes.Reader 需要重复读取时怎么用 Seek 重置位置Go bytes.Reader 需要重复读取时怎么用 Seek 重置位置
上一篇
Go bytes.Reader 需要重复读取时怎么用 Seek 重置位置
Go go vet copylocks 为什么提示复制 Mutex
下一篇
Go go vet copylocks 为什么提示复制 Mutex
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    81次使用
  • SuperCLUE中文大模型评测基准:功能、能力维度与应用指南
    SuperCLUE
    SuperCLUE是权威的中文大语言模型综合评测基准,涵盖语言理解、知识应用、AI Agent智能体及安全性等12项核心能力。通过多轮对话与客观测试,定期发布榜单与技术报告,为模型研发、优化及行业选型提供科学依据。
    239次使用
  • C-Eval中文评测基准:大语言模型多学科能力评估指南
    C-Eval
    深入了解C-Eval中文评估套件,涵盖52个学科与4级难度。本文详解其功能特点、Zero-shot/Few-shot使用方法及代码示例,助您全面评测LLM中文理解与泛化能力。
    166次使用
  • AI Prompt Library:免费AI提示词库,助力ChatGPT高效创作与营销
    AI Prompt Library
    探索AI Prompt Library免费资源库,涵盖营销、写作及多场景AI提示词。兼容ChatGPT、Claude等工具,一键复制优化输出,提升工作效率。
    99次使用
  • Generrated:DALL·E 2/3 AI绘画提示词灵感库与图像对比平台
    Generrated
    Generrated汇集9300+张DALL·E生成图像及对应提示词,支持查看完整图集、对比DALL·E 2与3版本差异,是AI绘图新手学习Prompt设计与获取创作灵感的实用工具。
    77次使用