Mysql行锁、表锁和间隙锁区别
【摘要】 Mysql行锁、表锁和间隙锁区别以下是MySQL行锁、表锁和间隙锁的详细解析及案例分析,结合核心机制与实战场景进行说明:🔐 一、锁类型详解1. 行锁(Row Lock)机制锁定数据表中的单行记录,是InnoDB引擎的默认锁机制。共享锁(S锁)允许多个事务并发读取同一行,但阻止任何写操作。SELECT*FROM users WHERE id =1 LOCK IN SHARE MODE;排他锁...
Mysql行锁、表锁和间隙锁区别
以下是MySQL行锁、表锁和间隙锁的详细解析及案例分析,结合核心机制与实战场景进行说明:
🔐 一、锁类型详解
1. 行锁(Row Lock)
- 机制
锁定数据表中的单行记录,是InnoDB引擎的默认锁机制。 - 共享锁(S锁)
允许多个事务并发读取同一行,但阻止任何写操作。 SELECT*FROM users WHERE id =1 LOCK IN SHARE MODE;
- 排他锁(X锁)
仅允许持有锁的事务读写数据,其他事务无法加锁或读写。 UPDATE users SET balance =100WHERE id =1; -- 自动加X锁
- 触发条件
需通过索引定位数据行。若WHERE条件无索引,行锁退化为表锁(如 UPDATE users SET status=1 WHERE name='Alice'
,若name
无索引)。 - 案例:
转账场景中,事务A锁定账户1,事务B锁定账户2,互相等待对方释放锁时形成死锁: 解决:按固定顺序访问资源(如先操作id小的账户)。-- 事务A
UPDATE accounts SET balance = balance -100WHERE id =1;
UPDATE accounts SET balance = balance +100WHERE id =2; -- 等待事务B释放id=2的锁
-- 事务B
UPDATE accounts SET balance = balance -100WHERE id =2;
UPDATE accounts SET balance = balance +100WHERE id =1; -- 等待事务A释放id=1的锁
2. 表锁(Table Lock)
- 机制
锁定整张表,MyISAM引擎默认支持,InnoDB在特定场景下使用。 - 读锁(S锁)
允许多事务并发读,但阻塞所有写操作。 - 写锁(X锁)
仅允许持有锁的事务读写,其他事务完全阻塞。 - 触发条件:
-
显式命令: LOCK TABLES users WRITE;
。 -
隐式升级:无索引的全表扫描(如 UPDATE users SET status=0
)、DDL操作(如ALTER TABLE
)。 - 案例:
库存表批量更新时,若未通过索引筛选,全表锁定导致并发写入阻塞: 优化:添加索引+分批更新(如UPDATE products SET stock = stock -10; -- 无WHERE条件,触发表锁
WHERE id BETWEEN 1 AND 1000
)。
3. 间隙锁(Gap Lock)
- 机制
锁定索引记录之间的间隙(如 id=5
到id=10
的空区间),防止其他事务插入数据,解决“幻读”。 - 触发条件:
-
在可重复读(RR) 隔离级别下使用范围查询或非唯一索引。 -
例如: SELECT * FROM users WHERE age BETWEEN 20 AND 30 FOR UPDATE;
锁定age
在20~30之间的所有间隙。 - 案例:
事务A查询年龄在20-30岁的用户并加锁,事务B尝试插入年龄25的新用户被阻塞: 规避:使用唯一索引精确查询(如-- 事务A
SELECT*FROM users WHERE age BETWEEN20AND30FORUPDATE; -- 锁定(20,30)的间隙
-- 事务B(被阻塞)
INSERTINTO users (name, age) VALUES ('Bob', 25);WHERE id=5
),或降级隔离级别至读已提交(RC)。
⚠️ 二、锁冲突与死锁
锁兼容性矩阵
|
|
|
|
---|---|---|---|
共享锁 (S) |
|
|
|
排他锁 (X) |
|
|
|
间隙锁 (Gap) |
|
|
|
说明:S锁兼容其他读操作,X锁与所有锁冲突,间隙锁仅兼容其他间隙锁。
死锁成因与解决
- 成因
事务循环等待资源(如A持X锁等B,B持X锁等A)。 - 解决方案:
- 设置超时
SET innodb_lock_wait_timeout = 5;
(默认50秒)。 - 死锁检测
启用 innodb_deadlock_detect=ON
自动回滚代价小的事务。 - 业务优化
按固定顺序访问资源(如所有事务先操作id小的行)。
🔧 三、优化策略与监控
-
索引优化
-
确保WHERE条件使用索引,避免行锁升级为表锁。 -
示例:为 products
表的category_id
加索引,缩小锁定范围。 -
事务设计
-
避免长事务:减少锁持有时间(如拆分大事务)。 -
使用乐观锁:通过版本号减少锁竞争(如 UPDATE ... WHERE version=old_version
)。 -
隔离级别调整
-
读已提交(RC):避免间隙锁,但可能幻读;可重复读(RR):需权衡一致性与并发。 -
锁监控工具
-
实时查看锁等待: SELECT*FROM information_schema.INNODB_LOCKS;
SELECT*FROM information_schema.INNODB_LOCK_WAITS; -
分析死锁日志: SHOW ENGINE INNODB STATUS;
。
💎 四、总结
- 行锁
高并发场景首选,需索引支持防升级。 - 表锁
简单但并发低,慎用于写频繁场景。 - 间隙锁
RR隔离级别防幻读的核心,但易引发阻塞。
优化铁律:索引精准锁范围,事务短小避冲突,监控死锁早干预。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)