0、前言
上一篇从MySQL层面上了解锁,那么这篇我们从存储引擎上来了解, 以MySQL默认存储引擎Innodb来说,看看有哪些锁?(MySQL版本为8)
1、Shared and Exclusive Locks -- 共享锁和排他锁
两者都是行级锁;
Shared Lock -- 共享锁(S), 也称为读锁。允许多个事务同一时刻并发读取同一记录,互不干扰。但不允许再加排他锁。
加锁方式:select * from table where xxx for share;
Exclusive Lock -- 排他锁(X),也称写锁。一个写锁会阻塞其它的写锁或读锁,保证同一时刻只有一个事务可以写入数据。
加锁方式:select * from table where xxx for update;
这里要注意下:
-
如果没有指定某行,而扫描了表中的所有记录,则相当于表级锁了。
-
在其他事务中没有操作的前提下,同一事务中是可以同时拥有某行的共享锁和排他锁的。
下面是的排他锁和共享锁的兼容性。
X |
S |
|
X |
互斥 |
互斥 |
S |
互斥 |
兼容 |
2、Intention Locks -- 意向锁
表级锁,指示事务稍后对表中的行需要哪种类型的锁(排他锁或共享锁)。所以又分为两种类型的意向锁。
IS(Intention Shared Lock):意向共享锁,表示事务打算在表中的各个行上设置共享锁。
IX(Intention Exclusive Lock): 意向排他锁,表示事务打算在表中的各个行上设置排他锁。
意向锁定协议如下:
在事务可以获取表中某行上的共享锁/排他锁之前,它必须首先获取该表上的意向共享锁/意向排他锁。例如:
-
select ... for share 需要先获取IS锁
-
select ... for update 需要先获取IX锁
下面是表级别的锁类型兼容性。
X |
IX |
S |
IS |
|
X |
互斥 |
互斥 |
互斥 |
互斥 |
IX |
互斥 |
兼容 |
互斥 |
兼容 |
S |
互斥 |
互斥 |
兼容 |
兼容 |
IS |
互斥 |
兼容 |
兼容 |
兼容 |
如果锁与现有锁冲突,则不授予该锁。
特别注意:
-
意向锁除了全表请求(例如:Lock tables ... write)外,不阻止任何其他内容。
-
意向锁的主要目的是表明有人正在锁定表中的行,或者将要锁定表中的行。
3、Record Locks -- 记录锁
记录锁是对索引记录的锁定。例如
select c1 from t where c1 = 10 for update;
表示防止任何其他事务插入、更新或删除t.c1=10的行。
4、Gap Locks -- 间隙锁
间隙锁是对索引记录之间的间隙的锁定。例如:
select c1 from t where c1 between 10 and 20 for update;
表示防止其他事务动(插入、更新或删除)t.c1在10~20中的记录。
特别注意:
-
间隙锁是可以共存的。例如:事务A在间隙上添加一个间隙共享锁(Gap S-Lock),事务B可以在同一间隙上增加间隙排他锁(Gap X-Lock)
-
间隙锁可以禁用。修改事务隔离级别至RC 或者 启用系统变量innodb_locks_unsafe_for_binlog
5、Next-Key Locks -- 下一个键锁
下一个键锁又称临界锁,是索引记录上的记录锁和索引记录之前的间隙上的间隙锁的组合。即Next-Key Lock 包含 Record Lock 和 Gap Lock。
默认情况下,InnoDB在可重复读取事务隔离级别下运行。在这种情况下,InnoDB使用next键锁进行搜索和索引扫描,从而防止幻读。
6、Insert Intension Locks -- 插入意向锁
插入意向锁是在行插入之前由插入操作设置的一种间隙锁。
7、AUTO-INC Locks -- 自增锁
AUTO-INC锁是一种特殊的表级锁,由插入到具有自动增量列的表中的事务使用。
8、总结
本次只是说明下相关概念, 下篇文章说下各种锁的实际用法,怎么查看加了什么锁,什么情况下会加什么锁。