MySQL常见的七种锁详细介绍

本文详细介绍了MySQL的八种锁,包括行锁、间隙锁、临键锁、共享锁/排他锁、意向共享锁/意向排他锁、插入意向锁和自增锁。特别强调了间隙锁和临键锁的作用、并发场景下的应用,以及在不同隔离级别下的行为。同时,解释了自增锁在不同锁定模式下的工作原理和自增列的处理策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、MySQL的八种锁

  • 行锁(Record Locks)

  • 间隙锁(Gap Locks)

  • 临键锁(Next-key Locks)

  • 共享锁/排他锁(Shared and Exclusive Locks)

  • 意向共享锁/意向排他锁(Intention Shared and Exclusive Locks)

  • 插入意向锁(Insert Intention Locks)

  • 自增锁(Auto-inc Locks)

    实际上,MySQL官网中还提到了一种预测锁,这种锁主要用于存储了空间数据的空间索引,本文暂不讨论。

1、行锁

这MySQL的官方文档中有以下描述:

A record lock is a lock on an index record. Record locks always lock index records, even if a table is defined with no indexes. For such cases, InnoDB creates a hidden clustered index and uses this index for record locking.

这句话说明行锁一定是作用在索引上的。

2、间隙锁

在MySQL的官方文档中有以下描述:

A gap lock is a lock on a gap between index records, or a lock on the gap before the first or after the last index record。

这句话表明间隙锁一定是开区间,比如(3,5)或者。在MySQL官网上还有一段非常关键的描述:

Gap locks in InnoDB are “purely inhibitive”, which means that their only purpose is to prevent other transactions from inserting to the gap. Gap locks can co-exist. A gap lock taken by one transaction does not prevent another transaction from taking a gap lock on the same gap. There is no difference between shared and exclusive gap locks. They do not conflict with each other, and they perform the same function.

这段话表明间隙锁在本质上是不区分共享间隙锁或互斥间隙锁的,而且间隙锁是不互斥的,即两个事务可以同时持有包含共同间隙的间隙锁。这里的共同间隙包括两种场景:其一是两个间隙锁的间隙区间完全一样;其二是一个间隙锁包含的间隙区间是另一个间隙锁包含间隙区间子集。间隙锁本质上是用于阻止其他事务在该间隙内插入新记录,而自身事务是允许在该间隙内插入数据的。也就是说间隙锁的应用场景包括并发读取、并发更新、并发删除和并发插入

在MySQL官网上关于间隙锁还有一段重要描述:

Gap locking can be disabled explicitly. This occurs if you change the transaction isolation level to READ COMMITTED. Under these circumstances, gap locking is disabled for searches and index scans and is used only for foreign-key constraint checking and duplicate-key checking.

这段话表明,在RU和RC两种隔离级别下,即使你使用select ... in share mode或select ... for update,也无法防止幻读(读后写的场景)。

虽然Gap锁只作用在隔离级别为RR及以上的数据库上,但是不意味着隔离等级为RC级别的不会使用,在RC级别,在进行外键约束检测和唯一键约束检测的时候,会使用到Gap锁,而正是这个duplicate-key checking导致了上文出现的死锁发生。

3、临键锁

在MySQL的官方文档中有以下描述:

A next-key lock is a combination of a record lock on the index record and a gap lock on the gap before the index record.

这句话表明临键锁是行锁+间隙锁,即临键锁是是一个左开右闭的区间,比如(3,5]。

在MySQL的官方文档中还有以下重要描述:

By default, InnoDB operates in REPEATABLE READ transaction isolation level. In this case, InnoDB uses next-key locks for searches and index scans, which prevents phantom rows.

个人觉得这段话描述得不够好,很容易引起误解。这里更正如下:InnoDB的默认事务隔离级别是RR,在这种级别下,如果你使用select ... in share mode或者select ... for update语句,那么InnoDB会在必要情况下使用临键锁,因而可以防止幻读;但即使你的隔离级别是RR,如果你这是使用普通的select语句,那么InnoDB将是快照读,不会使用任何锁,因而还是无法防止幻读

4、共享锁/排他锁

在MySQL的官方文档中有以下描述:

InnoDB implements standard row-level locking where there are two types of locks, shared (S) locks and exclusive (X) locks

### 三级标题:MySQL 常见类型及其用途 在 MySQL 中,常见机制主要包括表级、行级和页级,它们分别适用于同的应用场景。这些的使用主要取决于存储引擎的选择以及事务的需求。 #### 表级 表级MySQL 中粒度最大的一种,它对整个表进行定。这种的优点是加和释放的速度快,并且会出现死锁的情况;缺点是并发性能较差,因为一次只能有一个事务访问被定的表。MyISAM 存储引擎仅支持表级[^1]。可以通过以下 SQL 语句来显式地给表加: ```sql mysql> LOCK TABLES table_name WRITE; -- 排他 mysql> UNLOCK TABLES; ``` #### 行级 行级是 InnoDB 存储引擎所支持的一种更细粒度的机制,它可以针对表中的某一行或多行数据进行定。这种方式可以大大提高数据库的并发处理能力,但同时也增加了系统维护的成本。InnoDB 使用行级时,如果多个事务尝试修改同一行数据,则可能会发生阻塞或死锁情况[^2]。示例如下: ```sql -- 共享(读SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE; -- 排他(写SELECT * FROM table_name WHERE ... FOR UPDATE; ``` #### 意向 意向是一种表级别的,表示事务稍后将对表中的某些行施加共享或排他。意向本身并阻止其他事务的操作,而是用来防止其他事务添加表级别的。例如,在一个事务已经获取了某个表中某些行的排他的情况下,另一个事务就能再对该表施加表级排他[^3]。 #### 间隙 间隙用于定索引记录之间的“间隙”,或者说是范围。当执行查询操作时,除了定实际存在记录外,还会定可能插入新记录的位置,以避免幻读的问题。这是可重复读(Repeatable Read)隔离级别下的特性之一[^3]。 #### 乐观与悲观 从程序员的角度来看,还可以将分为乐观和悲观两种类型。乐观假设冲突经常发生,所以在提交更新的时候才会去检查是否违反数据一致性;而悲观则假定冲突总是会发生,所以在整个数据处理过程中都会保持住状态。通常情况下,乐观通过版本号或时间戳实现,而悲观则是利用数据库本身的机制实现[^2]。 ### 相关问题 1. 如何选择合适的机制来提高MySQL的并发性能? 2. 在高并发环境下,如何避免MySQL中的死锁问题? 3. 同的事务隔离级别如何影响MySQL的行为? 4. 如何监控和分析MySQL的使用情况? 5. 实现乐观的具体方法有哪些?各自优缺点是什么?
评论 34
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值