总结
MySQL数据库中的锁机制主要用于管理并发操作,以确保数据的一致性和完整性。MySQL支持多种类型的锁,按粒度和使用场景主要分为以下几类:
-
全局锁:
- 全局锁(如
FLUSH TABLES WITH READ LOCK
)可以锁定整个数据库实例,阻止所有表的写入操作,常用于数据备份等场景。
- 全局锁(如
-
表级锁:
- 表锁:锁定整张表,包括MyISAM引擎默认使用的表级锁,它在同一时刻只允许一个事务对表进行读取或写入。
- MDL(Metadata Lock,元数据锁):在InnoDB中自动加上的轻量级锁,用于保护表的结构变更操作,不影响DML语句,但在DDL操作时会阻塞其他事务对表的操作。
-
行级锁:
- 共享锁(Shared Lock/S锁):多个事务可同时获取同一行记录的共享锁,用于读取操作,互不阻塞。
- 排他锁(Exclusive Lock/X锁):一个事务对一行记录加排他锁后,其他任何事务不能对该行再加任何类型的锁,用于更新或删除操作。
- 间隙锁(Gap Lock):在范围查询条件下,InnoDB会在索引记录之间的间隙加上锁,防止其他事务插入新的记录造成幻读问题。
- 临键锁(Next-Key Lock):结合了行锁和间隙锁,不仅锁定记录本身,还锁定其前后的间隙。
-
意向锁:
- 意向共享锁(Intention Shared Lock/IS锁):事务打算在某一行上加共享锁时,先在表级别加意向共享锁。
- 意向排他锁(Intention Exclusive Lock/IX锁):事务打算在某一行上加排他锁时,先在表级别加意向排他锁。
在实际应用中,选择何种锁取决于业务需求和存储引擎特性:
- 对于读多写少且不需要高并发的场景,表级锁简单易用,开销较小。
- InnoDB存储引擎因其支持行级锁,在需要高并发处理和事务安全的应用中表现优秀,能够提供更好的并发性能和更细粒度的数据控制。
例子
熊大(代表事务A):“光头强,我正在看森林里某一棵果树的数据,你别动它!”
光头强(代表事务B):“好的熊大,那我就给你这棵树的数据加个‘共享锁’,咱们都能查看但都不能砍。”
熊大:“我要给苹果树挂牌子,光头强你先别碰这棵树。”
光头强:“明白,熊大,我现在要给它加个‘排他锁’,这样你就只能看我挂牌子,其他人暂时不能做任何操作。”
熊二(代表事务C):“嘿,我也要看果树林里的某个地方是否有新长出的小树苗。”
熊大:“哦,熊二,我已经查过那里没有树苗,并且为了防止光头强突然种下新树,我连空隙都上了‘间隙锁’。”
光头强:“哼,我要把这片区域的所有树木信息全部更新,为了避免你们误读,我会先加一个‘意向排他锁’,告诉你们我接下来可能要对这一片林子的每棵树都上排他锁。”