likes
comments
collection
share

不是?我的行锁怎么就变成表锁了?

作者站长头像
站长
· 阅读数 7

我的行锁在我不知情的情况下升级成了表锁

行锁和表锁

大家都知道,MySQL的InnoDB存储引擎支持事务,支持行级锁,那么大家有没有想过到底怎么实现这个行级锁呢?先埋个伏笔,往下看

那为什么要用行锁不用表锁,这个大家都懂,就是为了防止有并发的时候性能低这种情况嘛

所以如果在你什么都不知道的情况下,行锁自动升级成了表锁还是一件不好的事情的

索引分类

列举一下常见的索引:聚簇索引(主键索引)、唯一索引、普通索引、联合索引

  • 主键索引:自带最高效率的索引
  • 唯一索引:指该属性值重复率为0
  • 普通索引:指该属性值重复率 > 0

行锁升级为表锁的场景

  • 在不使用索引的情况下加锁,导致行锁升级为表锁
事务顺序事务A事务B
1⃣️begin;
2⃣️select * from user where age = 20 for update;
3⃣️begin;
4⃣️select * from user where age = 19 for update;
5⃣️commit;这个时候事务B才能拿到锁
6⃣️commit;

大家觉得在事务A提交之前,事务B能不能查得到?查询是不会加锁的,但是我们强制加锁为了方便测试而已

首先表中有两条数据

不是?我的行锁怎么就变成表锁了?

这个时候就有点纳闷了,我只是想差一条age=20的这一条数据,怎么就锁了整张表了呢?

可以从这个角度去思考,首先age字段是没有索引的,那数据库想要找到这条数据是不是要全表遍历?而且age字段加不了唯一索引


  • 使用普通索引的情况进行加锁

对age字段添加了普通索引

alter table test_user add index idx_age(age);
事务顺序事务A事务B
1⃣️begin;
2⃣️select * from user where age = 20 for update;
3⃣️begin;
4⃣️select * from user where age = 19 for update;
5⃣️commit;commit

不是?我的行锁怎么就变成表锁了?

可以发现在加了索引的情况下,行锁 是不会升级成表锁的


行锁是怎么加上去的?

还记得索引的B+树结构长什么样吗?

不是?我的行锁怎么就变成表锁了?

其实InnoDB的行锁就是通过给索引项进行加锁实现的