锁的结构
锁结构中有许多信息,其中比较重要的属性为:
- trx信息:这个锁结构与哪个事务所关联
- is_waiting:表示当前事务是否在等待
加锁到底是怎么加的呢?
加锁 = 为某条记录创建一个锁结构
不加锁 = 不创建一个锁结构
加锁成功或失败 = 锁结构中的is_waiting属性是true or flase , true代表加锁成功,false代表需要排队等待
这里要提一嘴加隐式锁
加隐式锁:在我们的行记录中有一个属性为trx_id属性,用它来标识该条记录所属哪个事务,从而不需要去生成锁结构从而浪费空间。当有其他事务【非所属事务】来尝试加锁,会先生成一个所属事务的锁结构,在生成一个自己的锁结构。总的来说加隐式锁只是延迟的锁结构的生成。
锁的分类
表锁
- 共享锁(s锁):事务要读取一条记录时,需要先获取该记录的s锁
- 独占锁(x锁):事务要读取一条记录时,需要先获取该记录的x锁
总结: s锁之后只可以加s锁,而x锁之后什么都加不了
- 意向共享锁(IS锁):事务要给某条记录加s锁时,需要先在表级别加一个is锁
- 意向独占锁(IX锁):事务要给某条记录加x锁时,需要先在表级别加一个ix锁
总结:
- 意向锁是一个表级锁,仅仅是为了有一个标识,为了之后要加表级别的s锁和x锁时快速判断能不能加锁,以免用遍历的方式去看表中有没有上锁的记录。
- is锁只关心后续的is锁,ix锁只关心后续的ix锁
行锁【重头戏来了】
record lock 记录锁
很容易理解就是仅仅锁了一条记录而已
gap lock 间隙锁
锁住某个记录的区间(a,b)
间隙锁的提出仅仅是为了防止插入幻影记录而提出的
那么问题来了如何锁(a,+无穷)? 还记得我们前面介绍数据页是提到的两条伪记录infimum记录和superemum记录,我们给superemum记录加锁就可以了,因为superemum记录是该数据页里最大的记录
next-key lock
next-key lock = record lock + gap lock ,既要锁住记录,又要锁住前面的间隙。
insert intention lock 插入意向锁
一个事务在插入一条记录时,需要判断插入的位置是否被别的事务加了gap锁,如果有的话,插入操作需要等待,直到拥有gap锁的事务提交为止,在等待的时候则需要产生一个插入意向锁。
插入意向锁就是一个is_waiting属性为false的锁结构,并不能阻拦任何事务去获取该记录上的锁
隐式锁
在我们的行记录中有一个属性为trx_id属性,用它来标识该条记录所属哪个事务,从而不需要去生成锁结构从而浪费空间。当有其他事务【非所属事务】来尝试加锁,会先生成一个所属事务的锁结构,在生成一个自己的锁结构。总的来说加隐式锁只是延迟的锁结构的生成