唠叨:我们使用mysql最常用的是innoDB存储引擎(关于mysql-存储引擎可以再另外一篇文章中了解到),因为它的特性:先来分析以下行级锁和表级锁的情况比较:
| 上锁速度 | 上锁开销 | 锁粒度 | 事务支持 | 并发支持 | 死锁 | |
表级锁 | 快 | 小 | 大 | 不支持 | 支持差 | 不会 | |
行级锁 (InnoDB独有) | 慢 | 大 | 小 | 支持 - ACID | 支持好 | 会 | |
要补充的一点:一个表级锁执行过程中 ,要是开启了事务,会强行释放表级锁
第一步:mylock开始表级锁 | |
第二步:另外一个session执行修改操作,进入阻塞 | |
第三步:开启事务 | |
第四步:发现更新操作执行成功了(表级锁已经被释放) |
一.这篇文章主要介绍的是行级锁
话不多说,进入到一个分析阶段----->
锁类别 | 本session | 另外session | |||||||
lock 行 | 非lock 行 /其他表行 | lock 行 | 非lock 行/其他表行 | ||||||
获取read | 获取write | 获取read | 获取write | 获取read | 获取write | 删除行 | 获取read | 获取write | |
read(共享锁) | OK | OK | OK | OK | OK | WAIT | WAIT | OK | OK |
write(排他锁) | OK | OK | OK | OK | OK | WAIT | WAIT | OK | OK |
2019/03/29:补充-当行级锁的lock语句where 不包含索引信息,会出现行级锁升级成表级锁的情况
1.读锁---select 字段 from 表名 where 条件 lock in share mode
(有人问不加where,那就是整张表的行锁,那行锁还有什么意义)
session--1
session---1
[SQL]BEGIN
受影响的行: 0
时间: 0.000s
开启事务
[SQL]SELECT * FROM mylock WHERE id = 2 LOCK IN SHARE MODE;
受影响的行: 0
时间: 0.001s
查询某行数据 并 加入行锁
查询锁住的行成功
[SQL]SELECT * FROM mylock WHERE id = 2;
受影响的行: 0
时间: 0.000s
查询未锁住的行成功
[SQL]SELECT * FROM mylock WHERE id = 3;
受影响的行: 0
时间: 0.001s
查询其他表未锁住的行成功
[SQL]SELECT * FROM myunlock WHERE id =2;
受影响的行: 0
时间: 0.000s
[SQL]INSERT INTO mylock VALUES(1,"s");
受影响的行: 1
时间: 0.000s
插入数据不受影响
[SQL]UPDATE mylock SET `name` = 'y' WHERE id = 2;
受影响的行: 1
时间: 0.001s
[SQL]DELETE FROM mylock WHERE id = 2;
受影响的行: 1
时间: 0.001s
本session下 update/delete 能操作被lock的行
本session执行其他表的增删改查不受影响,执行详情省略...
session--2 --update / delete进入到一个wait的状态
获取read锁成功 ,但是获取对应行的write锁也进入阻塞
2.写锁 --select 字段 from 表名 where 条件 for update
session--1
[SQL]BEGIN
受影响的行: 0
时间: 0.000s
[SQL]SELECT * FROM mylock WHERE id = 3 FOR UPDATE;
受影响的行: 0
时间: 0.000s
[SQL]SELECT * FROM mylock WHERE id = 3;
受影响的行: 0
时间: 0.000s
[SQL]INSERT INTO mylock VALUES(2,"s");
受影响的行: 1
时间: 0.000s
[SQL]UPDATE mylock SET `name` = 'e' WHERE id = 3;
受影响的行: 1
时间: 0.001s
[SQL]DELETE FROM mylock WHERE id = 3;
受影响的行: 1
时间: 0.001s
对于其他表的操作
[SQL]SELECT * FROM myunlock WHERE id =2;
受影响的行: 0
时间: 0.001s
[SQL]INSERT INTO myunlock VALUES(6, 'w');
受影响的行: 1
时间: 0.001s
[SQL]UPDATE myunlock SET NAME = 'd' WHERE id = 2;
受影响的行: 1
时间: 0.001s
[SQL]DELETE FROM myunlock WHERE id = 2;
受影响的行: 1
时间: 0.000s
session--2 - update / delete 会出现阻塞
获取读锁 和写锁都会进入阻塞: