sql

RC隔离级别下锁表现

2021-04-07  本文已影响0人  IT雪山

前提: mysql:8.0.20


截屏2021-04-07 11.13.43.png 截屏2021-04-07 14.37.51.png

非锁引

session1:begin;
session1:update user set name='aaa' where no='222';
session2:begin;
session2:update user set name='bbb' where no='333';(不阻塞)

session1:begin;
session1:update user set name='aaa' where no='222';
session2:begin;
session2:select * from user where no='333' for update;(阻塞)
解析:
由于no无锁引,因此只能走聚簇索引,进行全部扫描。加锁如下:
注:如果一个条件无法通过索引快速过滤,那么存储引擎层面就会将所有记录加锁后返回,然后由MySQL Server层进行过滤。因此也就把所有的记录,都锁上了。
但在实际中,MySQL做了优化,如同前面作用1所提到的。在MySQL Server过滤条件,发现不满足后,会调用unlock_row方法,把不满足条件的记录放锁 (违背了2PL的约束)。这样做,保证了最后只会持有满足条件记录上的锁,但是每条记录的加锁操作还是不能省略的

其实MySQL支持3种类型的读语句:

很显然,我们上边的例子中是因为事务T2执行UPDATE语句时使用了半一致性读,判断id列值为2这条记录的最新提交版本的num列值均不为UPDATE语句中WHERE条件中的'333',所以直接就跳过它们,不对它们加锁了。

有锁引

session1:begin;
session1:update user set name='aaa' where name='zhang';
session2:begin;
session2:update user set name='bbb' where name='zhang1';(不阻塞)

session1:begin;
session1:update user set name='aaa' where name='zhang';
session2:begin;
session2:select * from user where name ='zhang1' for update;(不阻塞)

结论: 加锁引的重要性

上一篇 下一篇

猜你喜欢

热点阅读