MySQL-锁机制1-表级锁与行级锁,排它锁与共享锁


表级锁与行级锁

表级锁:对整张表加锁,不需要花费时间去找某一行,开销小、加锁块、不会出现死锁;锁的颗粒度力度大,发生锁冲突的概率高,并发性低;
行级锁:对表中某行记录加锁,需要花时间去找某一行,开销大、加锁慢,会出现死锁;锁的颗粒度最小,发生锁冲突的概率最低,并发度高。


排它锁与共享锁

排它锁,又称为X锁、写锁;共享锁,又称为S 锁、读锁。写锁和读锁之间有以下的关系: 在并行事务A与B之间,A的读锁与B的读锁可以兼容的,A的写锁与B的读锁、A的读锁与B的写锁、A的写锁与B的写锁之间是互斥的,会发生事务的阻塞

1、一个事务对数据对象 O 加了 S 锁,可以对 O 进行读取操作但不能进行更新操作。加锁期间其它事务能对O 加 S 锁但不能加 X 锁;
2、一个事务对数据对象 O 加了 X 锁,就可以对 O 进行读取和更新。加锁期间其它事务不能对 O 加任何锁;
3、显示加锁:MySQL的默认隔离级别是可重复读;可以利用 select … lock in share mode强制获取共享锁,select … for update获取排它锁.

MySQL默认自动提交事务,所以需要设置一下手动提交,开启两个事务窗口,可以在MySQL事务章节中熟悉一下常用的事务处理命令。
下面通过实例理解一下排它锁和共享锁:

//设置事务为手动提交
set autocommit=0;
//查看设置是否成功
select @@autocommit;
//开启事务
begin;
//在事务一窗口  手动获取排它锁 这里选择stu表
select *from stu where uid=1 for update;
//在事务二窗口 查询uid=1时 发生阻塞
select *from stu where uid=1 for update;

在这里插入图片描述
上述实例中,因为是通过了uid索引添加的排它锁,在InnoDB存储引擎中,实际是对过滤条件的uid索引加了排它锁,此时为InnoDB的行级锁;此时其它事务窗口在访问该记录行的相关属性时,会发生阻塞,但是不影响查询同表中的其它记录行。


InnoDB行级锁

InnoDB的行锁是加在索引项上的,是在给索引加锁,并不是单纯的给行记录加锁;如果过滤条件没有索引的话,使用的就是表锁,而不是行锁。

1、InnoDB行锁是通过给索引上的索引项加锁来实现的,而不是给表的行记录加锁实现的,这就意味着只有通过索引条件检索数据,InnoDB才使用行级锁,否则InnoDB将使用表锁。
2、由于InnoDB的行锁实现是针对索引字段添加的锁,不是针对行记录加的锁,因此虽然访问的是InnoDB引擎下表的不同行,但是如果使用相同的索引字段作为过滤条件,依然会发生锁冲突,只能串行进行,不能并发进行。
3、即使SQL中使用了索引,但是经过MySQL的优化器后,如果认为全表扫描比使用索引效率差不多,此时会放弃使用索引,因此也不会使用行锁,而是使用表锁,比如对一些很小的表,MySQL就不会去使用索引。

下面举例一下,对非索引属性加锁,其它事务窗口否能查询该行记录或者同表中其它行的记录:

//先rollback一下
rollback;
//对非索引属性加锁
select *from stu where name='MM' for update;
//在另一个窗口查询    查同一行
select *from stu where name='MM' for update;
//查同表 不同行
select *from stu where name='GG' for update; 

在这里插入图片描述
通过上述实例可以看出,在对非索引属性name加排它锁之后,实际上是给stu表加了一个表级锁;此时,在事务二窗口无论是查询该行数据,还是同表中的其它行数据,都会发生事务阻塞。


总结

表级锁与行级锁颗粒度不同,但是它们都能包含排它锁和共享锁,它们之间的关系可以参考下图:

在这里插入图片描述

该章节通过实例对表级锁与行级锁、排它锁与共享锁进行了介绍;下一章节会继续介绍MySQL表机制的其它内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值