|
|
|
@ -846,7 +846,7 @@ InnoDB 存储引擎提供了个`innodb_autoinc_lock_mode`的系统变量,是
|
|
|
|
|
|
|
|
|
|
### Record Lock(记录锁)
|
|
|
|
|
|
|
|
|
|
记录锁就是为**某行**记录加锁,它封锁该行的**索引记录**:
|
|
|
|
|
**为单个行记录上的锁,总是会去锁住索引记录**。
|
|
|
|
|
|
|
|
|
|
```sql
|
|
|
|
|
-- id 列为主键列或唯一索引列
|
|
|
|
@ -869,6 +869,8 @@ UPDATE t_user SET age = 50 WHERE id = 1;
|
|
|
|
|
|
|
|
|
|
### Gap Lock(间隙锁)
|
|
|
|
|
|
|
|
|
|
间隙锁,想一下幻读的原因,其实就是行锁只能锁住行,但新插入记录这个动作,要更新的是记录之间的“间隙”。**所以加入间隙锁来解决幻读。**
|
|
|
|
|
|
|
|
|
|
**间隙锁**基于`非唯一索引`,它`锁定一段范围内的索引记录`。**间隙锁**基于下面将会提到的`Next-Key Locking` 算法,请务必牢记:**使用间隙锁锁住的是一个区间,而不仅仅是这个区间中的每一条数据**。
|
|
|
|
|
|
|
|
|
|
```sql
|
|
|
|
@ -885,6 +887,8 @@ SELECT * FROM t_user WHERE id > 1 AND id < 10 FOR UPDATE;
|
|
|
|
|
|
|
|
|
|
### Next-Key Lock(临键锁)
|
|
|
|
|
|
|
|
|
|
Gap Lock + Record Lock, 左开又闭。
|
|
|
|
|
|
|
|
|
|
临键锁是一种特殊的**间隙锁**,也可以理解为一种特殊的**算法**。通过**临建锁**可以解决`幻读`的问题。每个数据行上的`非唯一索引列`上都会存在一把**临键锁**,当某个事务持有该数据行的**临键锁**时,会锁住一段**左开右闭区间**的数据。需要强调的一点是,`InnoDB` 中`行级锁`是基于索引实现的,**临键锁**只与`非唯一索引列`有关,在`唯一索引列`(包括`主键列`)上不存在**临键锁**。
|
|
|
|
|
|
|
|
|
|
比如:表信息 `t_user(id PK, age KEY, name)`
|
|
|
|
@ -944,6 +948,8 @@ INSERT INTO table VALUES(100, 30, 'zhang');
|
|
|
|
|
|
|
|
|
|
### MVCC
|
|
|
|
|
|
|
|
|
|
https://mp.weixin.qq.com/s/KbOiJ8SKJ_wFZcIyDVGD9g
|
|
|
|
|
|
|
|
|
|
**MVCC**主要是通过**版本链**和**ReadView**来实现的。在Mysql的InnoDB引擎中,只有**已提交读(READ COMMITTD)**和**可重复读(REPEATABLE READ)**这两种隔离级别下的事务采用了MVCC机制。
|
|
|
|
|
|
|
|
|
|
- **版本链**
|
|
|
|
|