MySQL锁可以按照多个维度进行分类,下面我用最清晰的方式为你梳理所有分类方式:
一、按锁的粒度分类(最常用分类)
锁类型 | 作用范围 | 特点 | 适用引擎 | 示例场景 |
---|
表级锁 | 整张表 | 开销小、加锁快,并发度低 | MyISAM, MEMORY | 数据迁移、全表统计分析 |
行级锁 | 表中的单行 | 开销大、加锁慢,并发度高 | InnoDB, NDB | 订单处理、库存扣减 |
页级锁 | 数据页(16KB) | 介于表锁和行锁之间 | BDB(已淘汰) | 基本不再使用 |
二、按锁的模式分类
锁模式 | 简称 | 兼容性 | 示例SQL |
---|
共享锁 | S锁 | 允许其他事务读,阻止写 | SELECT ... LOCK IN SHARE MODE |
排他锁 | X锁 | 阻止其他事务读和写 | SELECT ... FOR UPDATE |
意向共享锁 | IS锁 | 表示事务准备加行级S锁 | 自动添加(检查表级兼容性) |
意向排他锁 | IX锁 | 表示事务准备加行级X锁 | 自动添加(检查表级兼容性) |
三、按锁的实现方式分类
类型 | 原理 | 优点 | 缺点 | 实现方式 |
---|
悲观锁 | 先加锁再操作 | 强一致性 | 性能开销大 | SELECT ... FOR UPDATE |
乐观锁 | 先操作,冲突时处理 | 高性能 | 需处理冲突 | 版本号/CAS机制 |
四、InnoDB特有的行锁算法
锁类型 | 锁定范围 | 解决的问题 | 触发条件 |
---|
记录锁 | 单个索引记录 | 精确匹配的更新 | WHERE id=1 FOR UPDATE |
间隙锁 | 索引记录之间的间隙 | 防止幻读 | 范围查询WHERE id>5 AND id<10 |
临键锁 | 记录+间隙(左开右闭) | 防止幻读 | RR隔离级别下的索引范围扫描 |
插入意向锁 | 特定插入位置的间隙 | 提高插入并发 | INSERT操作前自动获取 |
五、按锁的持有时间分类
类型 | 持有时间 | 示例 |
---|
短期锁 | 语句/事务执行期间 | 普通的SELECT FOR UPDATE |
长期锁 | 跨事务保持 | FLUSH TABLES WITH READ LOCK |
六、按锁的自动性分类
类型 | 获取方式 | 示例 |
---|
显式锁 | 手动获取 | SELECT ... FOR UPDATE |
隐式锁 | 自动获取 | INSERT/UPDATE/DELETE语句 |
最后,开发中:
能用行锁不用表锁,能用乐观锁不用悲观锁,锁的粒度越小越好!