知识点整理(十三)——mysql读已提交级别下的锁
知识点整理(十三)——mysql读已提交级别下的锁
逐暗者背景
上一次我们了解mysql在事务隔离级别为可重复读的情况下,加锁的各种现象。
这次来看一下在读已提交级别下加锁的各种情况。
实验
主键索引
等值更新
命中
1 | update lock_test set f_num = 0 where id = 10; |
除了表意向排它锁之外,就加了主键的记录锁,这个和RR级别一样。
未命中
1 | update lock_test set f_num = 0 where id = 11; |
这和RR级别不一样了,除了表意向排它锁之外,没有任何锁。
范围更新
命中
1 | update lock_test set f_num = 0 where id >= 5 and id <=15; |
这次也和RR级别不一样,除了表意向排它锁、主键记录锁之外没有间隙锁。
未命中
1 | update lock_test set f_num = 0 where id >= 5 and id <=7; |
这次依旧和RR级别不一样,但是和等值主键查询未命中是一样的,除了表意向排它锁之外,没有任何锁。
唯一索引
等值更新
命中
1 | update lock_test set f_num = 0 where f_uq = 10; |
数据库加了表意向排它锁、唯一索引记录锁、主键记录锁。
未命中
1 | update lock_test set f_num = 0 where f_uq = 11; |
未命中时和主键更新是一样的,除了表意向排它锁之外,没有任何锁。
范围更新
命中
1 | update lock_test set f_num = 0 where f_uq >= 5 and f_uq <=15; |
和等值更新一样,数据库加了表意向排它锁、唯一索引记录锁、主键记录锁。
未命中
1 | update lock_test set f_num = 0 where f_uq >= 5 and f_uq <=7; |
和等值更新一样,除了表意向排它锁之外,没有任何锁。
普通索引
- 等值更新
1 | update lock_test set f_num = 0 where f_index = 10; |
范围更新
1 | update lock_test set f_num = 0 where f_index >= 5 and f_index <=15; |
命中的时候都会加表意向排它锁、普通索引记录锁、主键记录锁。在未命中时,除了表意向排它锁之外,没有任何锁。
无索引
1 | update lock_test set f_num = 0 where f_num = 10; |
1 | update lock_test set f_num = 0 where f_num >= 5 and f_num <=15; |
和RR级别有很大区别,无论是等值更新还是范围更新,在命中时,只加了主键记录锁。未命中时,除了表意向排它锁之外,没有任何锁。
总结
总结一下,RC和RR级别加锁上来看,RR的加锁比较复杂,不仅多了间隙锁、临键锁,而且在未命中时也会加一些锁来保证可重复读。RC就比较简单,找到记录就加记录锁,没找到就不加锁。
由此也可以看出,除非业务场景必须要用到可重复读特性,不然RC的性能比RR高很多。
另外,虽然在RC中不使用索引更新比使用索引(唯一索引或普通索引)更新加的锁要少(只加主键记录锁),但是在没有索引的情况下数据库需要全表扫描,性能反而会下降,所以并不建议无索引更新。
评论
匿名评论隐私政策
✅ 你无需删除空行,直接评论以获取最佳展示效果