唠叨:我们使用mysql最常用的是innoDB存储引擎(关于mysql-存储引擎可以再另外一篇文章中了解到),因为它的特性:先来分析以下行级锁和表级锁的情况比较:

 

上锁速度

上锁开销

锁粒度

事务支持

并发支持

死锁

 

表级锁

不支持

支持差

不会

 

行级锁

(InnoDB独有)

支持 - ACID

支持好

 

要补充的一点:一个表级锁执行过程中 ,要是开启了事务,会强行释放表级锁 

第一步:mylock开始表级锁

mysql设置行级锁 mysql 行级锁使用_SQL

第二步:另外一个session执行修改操作,进入阻塞

mysql设置行级锁 mysql 行级锁使用_SQL_02

第三步:开启事务

mysql设置行级锁 mysql 行级锁使用_字段_03

第四步:发现更新操作执行成功了(表级锁已经被释放)

mysql设置行级锁 mysql 行级锁使用_mysql设置行级锁_04

一.这篇文章主要介绍的是行级锁

话不多说,进入到一个分析阶段----->

锁类别

本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的状态

mysql设置行级锁 mysql 行级锁使用_字段_05

mysql设置行级锁 mysql 行级锁使用_字段_06

获取read锁成功 ,但是获取对应行的write锁也进入阻塞

mysql设置行级锁 mysql 行级锁使用_mysql设置行级锁_07

 

   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 会出现阻塞 

mysql设置行级锁 mysql 行级锁使用_SQL_08

mysql设置行级锁 mysql 行级锁使用_mysql设置行级锁_09

获取读锁 和写锁都会进入阻塞:

mysql设置行级锁 mysql 行级锁使用_mysql设置行级锁_10

mysql设置行级锁 mysql 行级锁使用_SQL_11