一、按操作粒度划分
1. 表锁(Table Lock)
-
定义:锁定整个表,不允许其他线程对表执行冲突的操作。
-
特点:
- 粒度较大,开销较小。
- 并发性能较低,适用于简单查询和写入操作。
-
类型:
- 读锁(共享锁,S 锁) :多个线程可以同时读取表,但不能写入。
- 写锁(排他锁,X 锁) :加锁线程独占表,其他线程不能读写。
-
适用场景:MyISAM 存储引擎主要使用表锁。
2. 行锁(Row Lock)
-
定义:锁定表中的特定行记录。
-
特点:
- 粒度小,开销较大。
- 并发性能高,适合高并发场景。
-
类型:
- 共享锁(S 锁) :允许其他线程读取,但不允许写入。
- 排他锁(X 锁) :加锁线程独占行记录,其他线程不能读写。
-
适用场景:InnoDB 存储引擎支持行锁。
二、按锁的用途划分
1. 共享锁(S 锁,Shared Lock)
- 定义:允许多个线程读取数据,但不能修改数据。
- 语法:
SELECT ... LOCK IN SHARE MODE - 用途:数据只读或需要先读取再加锁修改的场景。
2. 排他锁(X 锁,Exclusive Lock)
- 定义:加锁线程独占资源,其他线程不能读写。
- 语法:
FOR UPDATE - 用途:事务中修改数据以保证一致性。
三、按事务隔离级别划分
1. 意向锁(Intention Lock)
-
定义:表级锁,用于描述事务即将加行锁的意图,避免锁冲突。
-
类型:
- 意向共享锁(IS 锁) :事务准备加行级共享锁。
- 意向排他锁(IX 锁) :事务准备加行级排他锁。
-
特点:
- 兼容性:意向锁之间不互斥,但与表级锁存在冲突。
-
用途:提高锁检测效率。
2. 记录锁(Record Lock)
- 定义:锁住单条行记录。
- 用途:行级操作时锁住特定记录,防止并发修改。
3. 间隙锁(Gap Lock)
-
定义:锁住一段范围,但不包括范围内的记录。
-
特点:
- 防止幻读,保证一致性。
- 对唯一索引无效。
-
用途:
REPEATABLE READ隔离级别下的范围查询。
4. Next-Key Lock
- 定义:记录锁 + 间隙锁。
- 用途:防止幻读,适用于范围查询。
四、其他锁
1. 意向锁(Intent Lock)
- 定义:用于标记表中某些行即将被加锁。
- 特点:优化并发锁检测的效率。
2. 自增长锁(AUTO-INC Lock)
- 定义:针对
AUTO_INCREMENT列的锁,保证自增字段的唯一性。 - 特点:MySQL 使用表级锁实现。
3. 临键锁(Insert Intention Lock)
- 定义:插入数据时锁住目标位置,但允许并发插入到不同位置。
- 特点:提升并发插入性能。
4. 元数据锁(Metadata Lock, MDL)
-
定义:保护表的元数据防止并发修改。
-
特点:
- 自动添加,不可禁用。
- 例如,在查询时防止表结构被修改。
-
用途:
DDL与DML操作的并发控制。
锁冲突和死锁
-
锁冲突:当两个事务持有相互竞争的锁时,可能导致冲突。
-
死锁:当两个事务互相等待对方释放资源时,形成死锁。
-
解决办法:
- 超时时间(
innodb_lock_wait_timeout)。 - 死锁检测(
InnoDB自动回滚其中一个事务)。
- 超时时间(