MySql 锁及相关知识
一、介绍
前面介绍了在并发事务下的可能出现的几种问题,脏读、脏写、不可重复读、幻读,几种隔离级别中 RU、RC、RR都是利用 MVCC 解决了脏读、不可重复读,在 RR 下解决了大部分的幻读,而完全解决 幻读 和 脏写 则需要利用 MySql 中的锁机制。
二、锁的几种类别
共享式和独占式:
共享式 S 锁:在读取一条记录的时候,需要先获取该记录的 S 锁。
独占式 X 锁:在事务改动一条记录的时候,就需要先获取该记录的 X 锁。
场景:在事务 T1 想要读取 A 记录的时候,获取了 A 记录的 S 锁,此时 T2 也想读取 A 记录,也同样可以获得 A 记录的 S 锁,因为 S 锁是共享的,但此时有 T1 和 T2 两个事务都拥有 A 记录的 S 锁,此时 T3 想要去修改 A 记录,想要去获取 A 记录的 X 锁,需要等 T1 和 T2 都释放其 S 锁,而当 T3 获得 A 记录的 X 锁之后, T4 想要获取 A 记录的 X 锁就需要等 T3 释放其 X 锁。
行锁和表锁:
对一条记录加锁称为行锁,对一个表进行加锁就称为表锁,行锁 和 表锁 同样也可以细分为 共享式 和 独占式,其含义相同。
场景:有表 F,表F中一行数据 A ,当 T1 线程获取 A 共享式锁 S ,此时其他线程可以获取 A 的共享式锁S,但不能获取 A 的独占式锁 X ,那如果此时 T2 线程想获取表 F 的共享式锁也是可以的,但如果 T3 想获取表 F 的独占式锁,就需要等待表 F 中所有锁都释放了,但如何检测这张表中有没有其他锁呢?遍历?太耗费时间,为了解决这个问题,就出现了意向锁。
意向锁也可以分为:意向共享锁、意向独占锁。
当一个事务想要去获取表中数据的共享锁或者独占锁的时候,就先在表上丢一个意向锁,表示我将要去获取里面的锁,这样如果一个线程想要获得表的独占锁的时候,可以先看表上面有没有意向锁,如果没有,说明没有表里面是没有锁的,则可以获取这个表的独占锁,而不需要遍历整张表
三、InnoDB中的锁
表级别锁 AUTO-INC 锁:
行级别锁:
1、Record Lock
(正经记录锁)有 X 锁和 S 锁之分,单行数据可以施加的锁。
2、Gap Lock
前面知道,在 RR 隔离级别下能解决大部分幻读的情况,解决方案可以用 MVCC 解决,也可以用锁解决。
但当用锁解决的时候,我们如果用 Record Lock 去给数据加锁,但出现幻读的时候,我想加锁的时候那些数据根本不存在,所以这样是行不通的,所以就出现了 Gap 锁。
在前面知道,聚簇索引的主键都是递增排列的,而我们读取的多条数据的主键肯定在某个范围,这里 Gap 锁的含义就是可以阻止某个范围内有数据插入,如果有数据想插入我正在读取的范围内,这个事务就会被阻塞,等我读完后才会继续,这样就有效的阻止了幻读的产生。
3、Next - Key - Lock
有时候我们锁住某条记录,有想该记录与前面的间隙之间没有数据插入,这时候就有了 Next - Key - Lock ,这个锁本质就是 Gap 锁 和 Record 锁的组合。
4、Insert Intention Lock
在事务插入一条数据时,首先得判断插入位置是否有 Gap 锁,如果有则需要等待。但 InnoDB 规定,事务在等待的时候也需要在内存中生成一个锁结构,表明有事务想要在某个间隙插入新纪录,但此时在等待状态,这是 Insert Intention Lock(插入意向锁)。
5、隐式锁
在内存中插入并维护一个锁并不是一件零成本的事情,出于节省的考虑,InnoDB 提出隐式锁。
场景:一个事务首先插入(注意)了一条记录(此时并没有与该记录相关联的锁结构),然后另一个事务立刻读取这条记录(获取这个记录的 S 锁)或者 (获取这条记录的 X 锁),此时前面一个没有锁的事务还没有提交,如果允许这种情况发生,就出现了脏读和脏写。这里就用到了隐式锁。
而要实现这个隐式锁,还需要借助之前提到的 事务ID,新插入的记录会记录其进行插入的事务ID,如果其他事务访问到此时的新纪录的时候,发现其事务ID还在活跃列表,就说明此时的插入事务还没有提交,就帮其创建一个 X 锁,然后自己进入等待状态,这个事务 ID 就充当了一个隐式锁的功能
为什么隔离级别 RR 只能避免大部分幻读?
假设有表 F ,T1 第一次执行普通查询的时候,生成了 ReadView(见MVCC原理),之后 T2 向 F 表新插入一个记录并提交(注意这个提交),之后 ReadView 并不能阻止 T1 对这条新数据进行修改(因为T2已经提交),如果执行修改后,这条数据的版本链就变成了 T1,之后如果 T1 再进行读取,就会读取到这条数据,也就可以把这条记录返回,也就出现了幻读,因为这种情况,所以 MVCC并不能阻止全部幻读。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY