Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.7k views
in Technique[技术] by (71.8m points)

mysql加了行锁后为什么还能加表读锁?不冲突吗?

在看意向锁的时候,我做了一个实验。

现有一个innodb引擎的student表,其中id为主键并且是唯一索引。

事务一我给student表某一行数据加上了行写锁,并未提交。

事务二我给student表加上了表读锁。发现竟然加上了。

既然事务一已经持有行锁了,为什么其它事务还能持有表锁。
查找资料无果,百思不得其解,望大佬指点迷津。

这是窗口1:
clipboard.png

这是窗口2:

clipboard.png


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

1、首先询问下你测试时使用的是MySql 默认的 RR可重复读 隔离级别吗? 如果是,则看下面:

2、你在第一个事务中,你使用 for update 当前读对 id=21 这行记录加上了行锁;并且没有提交事务;

3、然后在第二个事务中使用 lock table student read 对student表 "加表锁" ,注意 加表锁 这三个字被加上了引号,因为其实不是直接加的表锁,而只是实现 锁表 而已; innodb 存储引擎在 RR 隔离级别下是使用 Next-Key Locks 实现锁表的; 也可以理解为是用了行锁+间隙锁来实现锁表的操作!

所以,这也就可以解释为什么在对表中某行记录加上了行锁后,并且在行锁未释放时,也可以直接锁住整张表了。

4、具体可参考这篇文章:惊!史上最全的select加锁分析(Mysql),拿它去怒怼面试官,走起!

希望对你有帮助,谢谢!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...