一、简单介绍一下锁结构吧
谈到锁,我们都知道锁的作用,但是我们先来简单讲讲锁的结构吧🤣🤣🤣
其实锁就是内存中的一个结构,在我们执行一个事务之前,MySQL表中的记录本来是没有锁的,也就是说一开始是没有锁结构和这条锁记录相关联的,如图所示:
如果事务T1想要对这条记录做改动时,它先到内存中查看有没有与这条记录相关联的锁,如果没有这个锁,就会在内存中生成一个锁结构与这条记录关联,如图:
图中表示生成了一个锁结构,但是其中的两个属性是啥意思呢?
trx
信息:代表这个锁结构是哪个事务生成的is_waiting
:代表当前事务是否在等待
由于事务 T1 在改动该记录的时候没有其他的锁结构与这条记录相关联,所以事务 T1 生成的这个锁结构的 is_waiting
属性是 false, 我们就可以把这个场景叫做加锁成功。假如此时有另外的一个事务 T2 来改动这个记录,发现有一个锁记录与之关联,此时 事务T2 也会生成一个锁结构与之关联, 但是此时 T2 生成的锁结构的 is_waiting
属性时 true,因为 T1 此时在改动这条记录,事务 T2 就需要等待,我们把这个场景叫做加锁失败,如图所示:
在事务 T1 把事务提交之后,就会释放它的锁结构,然后去内存中查看有没有其他事务在等待,此时发现事务 T2 正在等待这个锁,就是把事务 T2 对应锁结构的 is_waiting 属性修改为 false,然后唤醒事务 T2 的线程 ,这样事务 T2 就获取到锁了,可以对该记录进行改动了,如图:
好了,以上讲解了最基本的锁结构、锁结构与事务之间的关联以及事务之间获取锁的调度,下面我们就正式开始讲解各种锁吧😅😅😅
二、各种各样的锁
在正式讲锁之前,我们先来看看什么是一致性读吧
事务利用 MVCC 进行的读取就叫做一致性读,或者叫做快照读。所有的普通 Select 语句在 RR 和 RC 隔离级别下都是一致性读。一致性读并不会对表中的任何记录加锁,其他事务可以自由对表的记录做改动
1、共享锁和独占锁
共享锁:英文名: Shared Locks
,简称 S
锁 。在事务要读取一条记录时,需要先获取该记录的 S锁 。
独占锁 :也常称 排他锁 ,英文名: Exclusive Locks
,简称 X
锁 。在事务要改动一条记录时,需要先获
取该记录的 X锁 。
假如事务 T1 首先获取了一条记录的 S锁 之后,事务 T2 接着也要访问这条记录:
- 如果事务 T2 想要获取这个记录的 S锁,那么事务 T2 也会获得该锁,说明 T1 和 T2 可以同时获取一条记录的 S 锁
- 如果事务 T2 想要获取这个记录的 X锁,那么事务 T2 就会阻塞,说明 T1 和