当前位置: 首页 > news >正文

Mysql--基础知识点--100-- insert VS select...for update 加锁

INSERTvsSELECT ... FOR UPDATE锁机制完整对比总结

一、锁全景对比表

维度INSERTSELECT ... FOR UPDATE
核心目的插入新数据,保证唯一性与数据完整性锁定已有数据,防止并发修改/删除,并避免幻读
表级意向锁✅ 加IX(意向排他锁),必加✅ 加IX(意向排他锁),必加
自增锁✅ 可能有(表级 AUTO-INC 锁或轻量级互斥锁),取决于innodb_autoinc_lock_mode和语句类型❌ 无
间隙锁通过插入意向锁X, GAP, INSERT_INTENTION)标记间隙,仅用于协调并发插入根据隔离级别和查询条件,可能加间隙锁X, GAP)或Next-Key 锁X),用于阻止幻读
记录锁✅ 插入成功后加排他记录锁X, REC_NOT_GAP),锁定新行✅ 对扫描到的每一行加排他记录锁X, REC_NOT_GAP
锁定对象新插入的行 + 插入位置的间隙意向查询条件匹配的所有现有行 + 查询范围覆盖的间隙(取决于条件)
锁范围极窄:仅新行及其间隙意向可能很宽:全表、范围或单行(取决于索引使用情况)
对并发插入的影响包容:同一间隙不同位置的并发INSERT互不阻塞阻塞:间隙锁会阻止其他事务在锁定范围内插入新行
对并发更新/删除的影响新行被排他锁保护,其他事务不能修改/删除它锁定的行被排他锁保护,其他事务不能修改/删除它们
死锁风险较低,但可能在唯一键冲突或间隙锁阻塞时发生较高,尤其是多表/多范围操作
典型应用场景数据写入、批量导入行级锁定读、乐观锁检查、防超卖

二、关键差异深度解析

1. 意向锁(IX)—— 两者相同
  • 都加表级 IX 锁:在任何行级写操作(INSERTUPDATEDELETESELECT ... FOR UPDATE)之前,InnoDB 都会自动在表上加 IX 锁。
  • 作用:声明事务将要修改某些行,用于快速判断与表级锁(如LOCK TABLES ... WRITE)的冲突。
  • 兼容性:多个 IX 锁之间完全兼容,不阻塞行级并发。
2. 自增锁(AUTO-INC)——INSERT特有
  • 何时出现:仅当表包含AUTO_INCREMENT列且INSERT需要生成新自增值时。
  • 锁类型
    • 表级自增锁AUTO-INC):在innodb_autoinc_lock_mode = 0(传统模式)或=1(连续模式)下执行INSERT ... SELECT等行数不确定的语句时出现,语句结束后释放。
    • 轻量级互斥锁:在默认模式(=1)下单行或确定行数的批量插入时使用,非传统锁,不出现于data_locks中。
  • SELECT ... FOR UPDATE:完全不涉及自增锁。
3. 间隙锁与插入意向锁 —— 本质不同
INSERTSELECT ... FOR UPDATE
锁名称插入意向锁(X, GAP, INSERT_INTENTION间隙锁(X, GAP)或 Next-Key 锁(X
目的声明“我打算在此间隙插入”,允许其他插入意向锁共存声明“此间隙禁止插入”,阻塞所有插入意向锁
兼容性插入意向锁之间兼容间隙锁与任何插入意向锁互斥
是否锁定记录否(仅间隙意向)否(间隙锁不锁记录),但 Next-Key 锁会锁记录

简记:插入意向锁是“我要进来”,间隙锁是“此路不通”。

4. 行锁(排他记录锁)—— 两者都有,但时机不同
  • INSERT:插入成功后才加排他记录锁,保护新行。
  • SELECT ... FOR UPDATE扫描时立即对现有行加排他记录锁,保护读取到的行。

三、锁的兼容性矩阵(行级锁部分)

锁类型插入意向锁间隙锁Next-Key 锁排他记录锁
插入意向锁✅ 兼容❌ 冲突❌ 冲突✅ 兼容(不同行)
间隙锁❌ 冲突✅ 兼容✅ 兼容✅ 兼容
Next-Key 锁❌ 冲突✅ 兼容❌ 冲突❌ 冲突
排他记录锁✅ 兼容✅ 兼容❌ 冲突❌ 冲突

说明:✅ 表示两个锁可以同时被不同事务持有;❌ 表示其中一个必须等待另一个释放。


四、验证方法(使用performance_schema.data_locks

-- 事务1BEGIN;INSERTINTOt(id)VALUES(10);-- 或 SELECT ... FOR UPDATE-- 事务2(观察锁)SELECTENGINE_TRANSACTION_ID,LOCK_TYPE,LOCK_MODE,LOCK_STATUS,LOCK_DATAFROMperformance_schema.data_locksWHEREOBJECT_NAME='t';

典型输出差异

操作表级锁行级锁(示例)
INSERT(自增列,模式1)TABLE,IXRECORD,X,INSERT_INTENTION
RECORD,X,REC_NOT_GAP
SELECT ... FOR UPDATE(范围查询)TABLE,IXRECORD,X(Next-Key)
RECORD,X,GAP
INSERT ... SELECT(模式0)TABLE,IX
TABLE,AUTO_INC
INSERT

五、实际开发建议

  1. 优先使用INSERT的天然并发性:对于单纯的数据写入,不要额外加SELECT ... FOR UPDATE,避免不必要的间隙锁阻塞。
  2. 需要“防插入”时用SELECT ... FOR UPDATE:例如实现“唯一库存扣减”前,需锁定范围防止幻读。
  3. 注意自增锁模式:高并发写入场景,建议innodb_autoinc_lock_mode = 2(交错模式),但需确保 binlog 格式为ROW
  4. 死锁排查INSERTSELECT ... FOR UPDATE混合使用时,注意间隙锁与插入意向锁的互斥关系,极易产生死锁。

一句话总结
INSERTIX + 插入意向锁 + 排他记录锁(以及可能的自增锁),主打高并发写入;
SELECT ... FOR UPDATEIX + 间隙锁/Next-Key锁 + 排他记录锁,主打强一致锁定读。
两者共享意向锁,但间隙锁与插入意向锁互斥,这是并发冲突与死锁的核心根源。

http://www.jsqmd.com/news/648170/

相关文章:

  • Ubuntu20.04编译Carla0.9.13实战:从环境配置到资源下载的完整避坑指南
  • Ubuntu系统中sogou输入法的安装与常见问题解决指南
  • EVA-01部署教程:Qwen2.5-VL-7B模型微调+领域适配(NERV战术语料)
  • 沟通力决定薪资:技术人的表达升级课
  • AI+Simulink新手避坑指南:从数据准备到模型部署的完整工作流
  • 硬件设计进阶:光耦在隔离驱动与信号转换中的实战解析
  • TLPI 第3章 练习:System Programming Concepts
  • 青少年软编等考五级题解目录
  • AutoSAR ETH Driver集成LwIP:Tc3XX平台下接收中断与发送缓冲区的配置与调试指南
  • 小红书博主必看:AI智能体如何5分钟搞定高颜值封面+3张内容页(附保姆级教程)
  • VPet存档迁移终极指南:如何快速升级旧版本数据到v2格式
  • python-gitlab CLI 工具深度解析:30个常用命令让 GitLab 管理变得简单
  • Ansible之Playbook(六):实例部署实战
  • MQTT over WebSocket实战指南:从EMQX安装到消息收发全流程
  • 该贴已作废
  • 告别深度依赖:手把手拆解BEVFormer如何用Transformer实现纯视觉BEV感知
  • 旋风分离器几何建模避坑指南:Star CCM+中布尔运算的5个常见错误
  • DeepSeek LeetCode 1434.每个个戴不同帽子的方案数 public int numberWays(List<List<Integer>> hats)
  • 从‘看图说话’到‘看截图答题’:MMMU-Pro如何模拟真实用户场景来‘拷问’AI?
  • Vue3 项目集成 OnlyOffice 在线编辑 + 自定义插件开发(一)
  • DeepSeek LeetCode 1439. 有序矩阵中的第 k 个最小数组和 public int kthSmallest(int[][] mat, int k)
  • Python 装饰器高级应用指南
  • 手把手教你用DigNet从scRNA-seq数据构建基因调控网络(附乳腺癌案例解析)
  • PyTorch 2.8镜像高清案例:Stable Video Diffusion生成电影级运镜视频截图
  • 玻璃幕墙的自爆原因,以及安全隐患分析
  • GeographicLib 地理计算库终极指南:从WMM2025地磁模型到高精度坐标转换实战
  • c++ string字符串详解
  • 渗透测试中的优先级选择:以Misdirection靶机为例解析如何避免死磕
  • IndexTTS-2-LLM与Tacotron2对比:新一代TTS优势分析
  • DeepSeek linux-6.19/net/ipv6/addrconf.c 源码分析