mysql加了行锁后为什么还能加表读锁?不冲突吗?
在看意向锁的时候,我做了一个实验。
现有一个innodb引擎的student表,其中id为主键并且是唯一索引。
事务一我给student表某一行数据加上了行写锁,并未提交。
事务二我给student表加上了表读锁。发现竟然加上了。
既然事务一已经持有行锁了,为什么其它事务还能持有表锁。
查找资料无果,百思不得其解,望大佬指点迷津。
这是窗口1:
这是窗口2:
回答
1、首先询问下你测试时使用的是MySql 默认的 RR可重复读 隔离级别吗? 如果是,则看下面:
2、你在第一个事务中,你使用 for update 当前读对 id=21 这行记录加上了行锁;并且没有提交事务;
3、然后在第二个事务中使用 lock table student read 对student表 "加表锁" ,注意 加表锁 这三个字被加上了引号,因为其实不是直接加的表锁,而只是实现 锁表 而已; innodb 存储引擎在 RR 隔离级别下是使用 Next-Key Locks
实现锁表的; 也可以理解为是用了行锁+间隙锁来实现锁表的操作!
所以,这也就可以解释为什么在对表中某行记录加上了行锁后,并且在行锁未释放时,也可以直接锁住整张表了。
4、具体可参考这篇文章:惊!史上最全的select加锁分析(Mysql),拿它去怒怼面试官,走起!