MySQL --- 读书笔记 --- 锁

2. 并发事务访问相同记录的情况

2.1 读-读情况

读取操作并不会对记录有任何影响,所以允许这种情况的发生

2.2 写-写情况

对相同记录做出改动,在这种情况下会出现脏写情况,任何一种隔离级别都不允许这种情况的发生,所以多个未提交事务对一条记录做改动时,都需要排队执行,排队的过程是通过实现的。

这个所谓是一个内存中的结构,在事务执行之前本来是没有锁的,当一个事务想对记录做改动时,首先看看内存有没有与这条记录相关联的锁结构,当没有的时候,就会生成一个与之关联的结构,这称为获取锁成功

然后在这个事务提交之前,另一个事务也想对这条记录改动时,也会想查看与之关联的结构,当发现有锁时,也会生成一个锁结构与之关联,但是需要等待,这称为获取锁失败

当第一个事务结束后,就会把相应的锁结构释放,并查看是否别的事务在等待,如果有,就会唤醒该事务

2.3 读-写或写-读情况

当一个事务读取记录,另一个事务改动记录,这种情况下就会出现脏读不可重复读幻读问题

  • 读写都加锁
  • 读取记录采用MVCC,改动记录采用

锁的不同角度分类

3.1 从数据操作的类型划分

对于InnoDB来说,读锁/写锁可以加在表上,也可以在行上

1. 读锁/共享锁

英文S表示,针对同一份数据,多个事务的读操作同时进行,相互不阻塞

SELECT ... FOR SHARE;

2. 写锁/排他锁

英文X表示,在当前操作未完成前,阻断其他写锁或读锁

SELECT ... FOR UPDATE

3.2 从数据操作的粒度划分

1. 表锁

该锁会锁定这个张表的记录,是MySQL中最基本的锁策略,并不依赖于存储引擎,它的开销最小,可以很好的避免死锁问题,但是随之而来的锁竞争发生的概率也会提高,导致并发率大打折扣

  • 表级别的S、X锁
  • 意向锁

InnoDB支持多粒度锁,允许行级锁与表级锁共存

  1. 意向锁是为了协调行锁和表锁的关系
  2. 意向锁是一种不与行级锁冲突的表级锁
  3. 表明“某个事务正在某些行持有锁或该事务准备去持有锁”
  • 自增锁
  • 元数据锁

意向锁是由存储引擎维护,用户无法手动操作,在为数据行加S/X锁时,会先获取该数据行所在数据表的意向锁

意向锁解决的问题:假设有两个事务t1和t2,当t2想要给表加上S/X锁,那么它需要检查表中每一行记录是否存在锁,但是如果我们有意向锁,当t1给表中某些记录加锁时,首先给表添加意向锁,然后当t2想要进行表级锁时,就可以直接知道表中某些记录被其他事务锁定了

2. 行锁

  • 优点:粒度小,发生锁冲突概率低,并发度高
  • 缺点:开销大,加锁慢,容易出现死锁
  1. 记录锁
  2. 间隙锁

在解决幻读问题上,当使用的方案时,事务读取记录时,幻影记录还没添加,我们无法给幻影记录加上记录锁,这时就要用到间隙锁

假设给一条记录加上间隙锁,那么这条记录的前边就不允许插入记录,或者说当主键3和主键8之间没有其他记录,当给主键8这条记录加上间隙锁,那么不允许插入主键是3-8之间的记录

无论是共享间隙锁或者排他间隙锁,并不限制其他事务对这条记录加记录锁或者间隙锁

  1. 临键锁

当既想锁定某条记录,又阻止其他事务在该记录的前边间隙插入新记录,这时就用到临键锁,它只在InnoDB中的可重复读的隔离级别下使用,InnoDB的默认锁就是临键锁

本质是一个记录锁和间隙锁的合体

  1. 插入意向锁

InnoDB规定事务在等待的时候也需要在内存中生成一个锁结构

当事务希望插入新记录时,但是遇到间隙锁需要等待时,生成一个插入意向锁,它是一种Gap锁不是意向锁

它是一种特殊的间隙锁,当插入记录之间不同时,互相不排斥

posted @   huang1993  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示