mysql幻读是怎么出现的_mysql并发问题分析
发布时间 - 2026-02-02 00:00:00 点击率:次幻读只在“当前读”下真实发生;RR隔离级别下普通SELECT是快照读,不产生幻读,而SELECT...FOR UPDATE等当前读语句因加锁机制缺陷(如无索引时仅行锁、不锁间隙)可能导致幻读。
幻读只在“当前读”下真实发生
很多人误以

SELECT 也会幻读,其实不会——RR 下的普通查询是快照读,读的是事务启动时的 MVCC 快照,新插入的行根本不可见。真正出现幻读的,一定是用了 SELECT ... FOR UPDATE、SELECT ... LOCK IN SHARE MODE 或 UPDATE/DELETE 这类“当前读”语句。
典型现象:事务 A 执行 SELECT * FROM orders WHERE status = 'pending' FOR UPDATE 得到 5 行;事务 B 插入一条 status = 'pending' 的新订单并提交;事务 A 再次执行相同语句,突然返回 6 行——多出来的那条就是“幻行”。
为什么 RR 隔离级别仍挡不住幻读
关键在于 InnoDB 的加锁机制:RR 级别下,WHERE 条件无索引或索引不生效时,InnoDB 只能走全表扫描,此时仅对**实际命中的记录**加行锁(Record Lock),而对未命中但落在查询范围内的“间隙”(Gap)不加锁——这就给其他事务留下了插入空间。
- 如果
status字段没建索引,WHERE status = 'pending'会锁住所有扫描到的行,但间隙不锁 → 幻读可发生 - 如果
status有索引,且查询能走索引,InnoDB 会升级为Next-Key Lock(行锁 + 间隙锁),覆盖等值查询的前后间隙 → 大概率阻止幻读 - 但如果查询条件是
WHERE status > 'a'这类范围查询,即使有索引,也可能只锁部分间隙,仍存在漏插风险
真正有效的解决方式不是调高隔离级别
用 SERIALIZABLE 能彻底消灭幻读,但代价是所有 SELECT 都隐式加锁,高并发下极易锁等待甚至死锁,线上基本不用。
更务实的做法是结合场景主动控制:
- 对关键业务逻辑(如库存扣减、订单生成),在事务开头就用
SELECT ... FOR UPDATE锁住整个范围,且确保该字段有合适索引 - 插入前先做一次“存在性校验查询”,但必须搭配
FOR UPDATE,否则校验和插入之间仍有窗口 - 用唯一约束(
UNIQUE KEY)替代应用层判断,让数据库直接拦截重复插入(注意:这防的是重复,不防幻读本身) - 业务上接受“最终一致性”的,可改用乐观锁(如版本号字段 +
WHERE version = ?)配合重试
最容易被忽略的坑:d=5 这种无索引条件
看这个经典例子:SELECT * FROM t WHERE d = 5 FOR UPDATE,而 d 字段没有索引。InnoDB 只会对实际满足 d = 5 的行(比如 id=5)加行锁,其余扫描过的行(id=0,10,15…)不加锁,间隙更不锁。这时别人就能在 id=1、id=2 等任意空隙插入 d = 5 的新行,下次当前读就看到幻行了。
这不是 MySQL 的 bug,而是设计取舍:MVCC 解决快照读一致性,锁机制解决当前读一致性,两者分工明确。想靠 RR 一招鲜解决所有并发问题,本身就是对隔离级别的误解。
# mysql
# 为什么
# for
# select
# delete
# 并发
# 数据库
# bug
# 加锁
# 的是
# 这类
# 死锁
# 只在
# 锁住
# 能走
# 也会
# 很多人
# 能在
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
html5audio标签播放结束怎么触发事件_onended回调方法【教程】
网站制作壁纸教程视频,电脑壁纸网站?
小视频制作网站有哪些,有什么看国内小视频的网站,求推荐?
如何快速上传建站程序避免常见错误?
Laravel如何处理JSON字段的查询和更新_Laravel JSON列操作与查询技巧
Laravel如何实现用户角色和权限系统_Laravel角色权限管理机制
DeepSeek是免费使用的吗 DeepSeek收费模式与Pro版本功能详解
黑客如何利用漏洞与弱口令入侵网站服务器?
Android仿QQ列表左滑删除操作
制作公司内部网站有哪些,内网如何建网站?
网站制作免费,什么网站能看正片电影?
php json中文编码为null的解决办法
Laravel如何正确地在控制器和模型之间分配逻辑_Laravel代码职责分离与架构建议
Laravel如何使用Socialite实现第三方登录?(微信/GitHub示例)
Laravel怎么在Blade中安全地输出原始HTML内容
linux写shell需要注意的问题(必看)
谷歌Google入口永久地址_Google搜索引擎官网首页永久入口
Laravel如何发送系统通知?(Notification渠道示例)
千问怎样用提示词获取健康建议_千问健康类提示词注意事项【指南】
javascript基于原型链的继承及call和apply函数用法分析
Laravel怎么实现验证码功能_Laravel集成验证码库防止机器人注册
VIVO手机上del键无效OnKeyListener不响应的原因及解决方法
如何使用 jQuery 正确渲染 Instagram 风格的标签列表
Laravel如何使用Laravel Vite编译前端_Laravel10以上版本前端静态资源管理【教程】
Gemini手机端怎么发图片_Gemini手机端发图方法【步骤】
Laravel如何实现全文搜索功能?(Scout和Algolia示例)
如何在阿里云域名上完成建站全流程?
Laravel如何实现数据导出到PDF_Laravel使用snappy生成网页快照PDF【方案】
Laravel如何使用模型观察者?(Observer代码示例)
如何在阿里云香港服务器快速搭建网站?
如何在腾讯云服务器快速搭建个人网站?
使用C语言编写圣诞表白程序
java ZXing生成二维码及条码实例分享
香港服务器选型指南:免备案配置与高效建站方案解析
广州网站制作公司哪家好一点,广州欧莱雅百库网络科技有限公司官网?
Laravel如何实现本地化和多语言支持?(i18n教程)
Laravel如何使用Passport实现OAuth2?(完整配置步骤)
Edge浏览器怎么启用睡眠标签页_节省电脑内存占用优化技巧
Laravel如何配置.env文件管理环境变量_Laravel环境变量使用与安全管理
Laravel Asset编译怎么配置_Laravel Vite前端构建工具使用
Python文件异常处理策略_健壮性说明【指导】
网站建设要注意的标准 促进网站用户好感度!
如何在万网开始建站?分步指南解析
公司门户网站制作公司有哪些,怎样使用wordpress制作一个企业网站?
,在苏州找工作,上哪个网站比较好?
Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】
,交易猫的商品怎么发布到网站上去?
Laravel控制器是什么_Laravel MVC架构中Controller的作用与实践
laravel怎么配置和使用PHP-FPM来优化性能_laravel PHP-FPM配置与性能优化方法
如何正确选择百度移动适配建站域名?

