『MySQL』跟面试官侃半小时MySQL事务隔离性,从基本概念深入到实现( 二 )
如果这时候有事务C希望获得行r的排它锁 , 那么就必须等待事务A和事务B释放行r的共享锁之后 , 才能获得排它锁 , 这种叫做锁不兼容 。
本文插图
普通的select不会对行上锁 , 而select…lock in share mode会上共享锁 , select…for update会上排它锁 。
- 对于普通的select的读取方式 , 称为”快照读“ , 也叫”一致性非锁定读“ 。
- 对于带锁的select读取 , 或者update tb set a = a+1(读取a的当前值) , 称为“当前读” , 也叫“一致性锁定读” 。
2.2 多版本并发控制MVCC 如果说上面的行锁是一种悲观锁 , 那么MVCC就是一种乐观锁的实现方式 , 而且是一种很常用的乐观锁实现方式 。
所谓多版本 , 就是一行记录在数据库中存储了多个版本 , 每个版本以事务ID作为版本号 。 InnoDB 里面每个事务有一个唯一的事务 ID , 是在事务开始的时候向InnoDB的事务系统申请的 , 并且按照申请顺序严格递增的 。 假如一行记录被多个事务更新 , 那么 , 就会产生多个版本的记录 。
以某一行数据作为例子:
本文插图
经过两次事务的操作 , value从22变成了19 , 同时 , 保留了三个事务id , 15、25、30 。
在每个记录多版本的基础上 , 需要利用“一致性视图” , 来做版本的可见性判断 。
这里 , 我们要区分MySQL里面的两个”视图”概念:
- 一个是view , 通过语法create view … 实现 , 主要创建一个虚拟表 , 用来执行查询语句 。
- 一个是InnoDB用来实现mvcc的一致性视图(consistent read view) , 纯逻辑概念 , 没有物理结构 , 定义了在事务期间 , 你能看到哪些版本的数据 。
- “读未提及”级别下 , 没有一致性视图
- “读已提交”级别下 , 会在 每个SQL开始执行的时候 创建一致性视图
- “可重复读”级别下 , 会在 每个事务开始的时候 创建一致性视图
- “串行化”级别下 , 直接通过加锁避免并发问题
以“可重复读”级别为例 。
- 当一个事务开启的时候 , 会向系统申请一个新事务id
- 此时 , 可能还有多个正在进行的其他事务没有提交 , 因此在瞬时时刻 , 是有多个活跃的未提交事务id
- 将这些未提交的事务id组成一个数组 , 数组里面最小的事务id记录为低水位 , 当前系统创建过的事务id的最大值+1记录为高水位
- 这个数组array 和 高水位 , 就组成了“一致性视图” 。
在当前事务中 , 读取其他某一行的记录 , 对其中的版本号的可见性判断有五种情况(建议自己跟着捋一捋 , 挺重要的):
- 如果版本号小于“低水位” , 说明事务已经提交 , 那肯定 可见;
- 如果版本号大于“高水位” , 说明这行数据的这个事务id版本是在快照后产生的 , 那肯定 不可见;
推荐阅读
- 霍格沃兹测试学院:内推 | 跳槽吗?可年前面试,年后入职的那种
- 「大咖说生活」你会怎么做?女子淡定回答被录取,面试官:看到男女同事抱在一起
- 「月影说职场」中专生答对被录用,面试官:1+1等于多少?4个大学生应聘失败
- 『数据库』4月数据库流行度排行:MySQL 成事实王者,国产openGauss引期待
- [面试]国培教育—2020江西公务员面试热点:生态菜“种”出致富路
- 【怪咖搞笑】幽默笑话:昨天去公司面试 碰到个美女面试官,原创
- 『怪咖搞笑』碰到个美女面试官,幽默笑话:昨天去公司面试
- 【鱼堂主爱思考】在办公室发现我牙齿上有菜叶,该怎么提醒才可以被录用,面试官问
- 【面试】Google 教你视频面试
- 『姵来晓晓看娱乐』并存入mysql数据库,超详细,python3快速爬取房源信息
