mysql行锁是如何实现的_mysql底层机制解析
行锁依赖索引无索引则退化为表锁InnoDB通过record lock、gap lock和next-key lock实现行级锁定其中next-key lock用于防止幻读但易引发死锁。行锁是通过索引实现的没索引就退化为表锁MySQL 的 InnoDB 行锁如 SELECT ... FOR UPDATE 或 UPDATE本身不直接锁“行”而是锁住索引记录record lock或索引间隙gap lock。这意味着如果 WHERE 条件字段没有索引InnoDB 无法快速定位目标行只能走全表扫描此时会为**扫描到的每条记录加锁**实际效果等同于锁整张表。常见错误现象UPDATE users SET status1 WHERE phone138... 执行极慢、并发更新卡死——查一下 EXPLAIN发现 type 是 ALLkey 为 NULL基本就是这个原因。唯一索引等值查询 → 只锁匹配的那一条索引记录record lock普通索引等值查询 → 锁匹配记录 对应的主键记录因为二级索引不存完整行需回表范围查询如 WHERE id 100→ 可能触发 gap lock 或 next-key lock锁住区间而非单行无索引字段 → 全表扫描逐行加锁本质是表级争用next-key lock 是行锁间隙锁的组合防幻读但易死锁InnoDB 默认事务隔离级别是 REPEATABLE READ为防止幻读它用 next-key lock前开后闭区间代替单纯的 record lock。比如 SELECT * FROM t WHERE a 5 FOR UPDATE若 a 是普通索引且值 5 存在则锁住的是 (3,5] 或 (5,7] 这样的区间具体取决于索引结构。这带来两个关键影响看似只改一行实际可能锁住一大片相邻记录阻塞其他事务插入或更新邻近值多个事务按不同顺序访问索引区间时极易形成循环等待 → 死锁。例如事务 A 先锁 (1,3] 再锁 (5,7]事务 B 反过来先锁 (5,7] 再锁 (1,3]使用 SELECT ... LOCK IN SHARE MODE 同样受 next-key lock 影响不只是 FOR UPDATE显式加锁语句的行为差异FOR UPDATE vs LOCK IN SHARE MODE两者都走索引才能生效为行锁但语义和兼容性完全不同 微软爱写作 微软出品的免费英文写作/辅助/批改/评分工具