本文已参与「新人创作礼」活动,一起开启掘金创作之路。
MySOL中的锁,按照锁的粒度分,分为以下三类:1.全局锁。2.表级锁。3.行级锁。
全局锁
对整个数据库实例进行加锁,使用场景:全库的逻辑备份,保证数据的完整性,在此期间,所有DML语句都是阻塞的,而DQL不受影响
- 听上去跟一致性视图作用差不多?那为什么要需要全局锁呢?-——因为有些引擎不支持一致性视图
表级锁
表级锁,每次操作锁住整张表。
对于表级锁,主要分为以下三类:
- 表锁
- 元数据锁(meta data lock, MDL)
- 意向锁
表锁
对于表锁,分为读锁跟写锁。但是锁定粒度大,发生锁冲突的概率高,不建议使用
- 读锁加上之后,只允许读(包括任意连接),不允许写
- 写锁加上之后,只允许当前连接进行读写操作,其他连接不允许读写操作
DML
在 MySQL 5.5 版本中引入了 MDL,当对一个表做增删改查操作的时候,加 MDL 读锁;当要对表做结构变更操作的时候,加 MDL 写锁。读-读不互斥,其他皆互斥
意向锁
为了避免DML语句在执行时,行锁与表锁之间的冲突,在InnoDB中引入了意向锁,使得表锁不用检查每行数据是否加锁,而是使用意向锁来减少表锁的检查(有点类似synchronized锁升级的偏向锁)
行级锁
每次操作锁住对应的行数据。锁的粒度小,并发度最高。InnoDB存储引擎支持行锁
原理:
- 行锁是通过对索引上的索引项加锁来实现的.
- 行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。这个就是两阶段锁协议。
死锁和死锁检测
两个事务之间发生死锁之后,有两种策略进行解决:
- 等待超时
- 开启死锁检测,发生死锁后,主动回滚某一条事务