『MySQL』跟面试官侃半小时MySQL事务隔离性,从基本概念深入到实现( 三 )
系统创建过的事务id:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
事务A启动 , 拍个快照
此时未提交的事务id有:7 , 8 , 9
一致性视图:数组array[7,8,9] + 高水位16(15+1)
对于任意一行数据的可见性判断如下:
1)小于7的 , 可见
2)大于16的 , 说明是快照后产生的 , 不可见
3)10-15 , 不在数组array中 , 说明已经提交了 , 可见
4)7 , 8 , 9在array中 , 说明未提交 , 不可见
两个重要结论:
- InnoDB 利用了“所有数据都有多个版本”的这个特性 , 实现了“秒级创建快照”的能力 。
- MVCC的实现 , 就是根据当前事务的事务id为依据创建“一致性视图” , 利用一致性视图来判断数据版本的可见性 。
1)并发select&update 案例
id=1 的value初始为1 。
本文插图
我们看下 , 在不同隔离级别 , Time5、Time7、Time9事务A查询到的value 分布为多少 。
- “读未提交”:2 , 2 , 2
- “读以提交”:1 , 2 , 2
- “可重复读”:1 , 1 , 2
- 串行化:1 , 1 , 2(注意 , 这里在事务A提交前 , 事务B都会阻塞 , 直到事务A提交后才能执行)
【『MySQL』跟面试官侃半小时MySQL事务隔离性,从基本概念深入到实现】id=1 的value初始为1 , 在可重复读级别:
本文插图
我们看一下 , 你猜猜事务A和事务B读取的value是多少?
答案是:1 和 3
可能会产生困惑 , 事务A在启动后快照 , 所以读到了1是正常的 , 但是事务2在启动的时候快照了 , 然后在自己的事务中+1 , 怎么会读到3而不是2呢?
原因很简单 , 即使是在可重复读的级别 , 事务 更新数据 的时候 , 只能用当前读(想想也能理解 , 不然update就出现数据不一致了) 。
如果当前的记录的行锁被其他事务占用的话 , 就需要进入锁等待 。 而读提交的逻辑和可重复读的逻辑类似 , 它们最主要的区别是:在可重复读隔离级别下 , 只需要在事务开始的时候创建一致性视图 , 之后事务里的其他查询都共用这个一致性视图;在读提交隔离级别下 , 每一个语句执行前都会重新算出一个新的视图 。
这里 , 我们需要注意的是事务的启动时机 。
- begin/start transaction 命令并不是一个事务的起点 , 在执行到它们之后的第一个操作 InnoDB 表的语句 , 事务才真正启动,一致性视图是在执行第一个快照读语句时创建的 。
- 如果你想要马上启动一个事务 , 可以使用 start transaction with consistent snapshot 这个命令 , 一致性视图是在执行 start transaction with consistent snapshot 时创建的 。
- 第一:事务的隔离级别为可重复读 , 且是当前读
- 第二:幻读仅专指新插入的行 , 在范围查询中 , 后一次查询出现了新的数据行 。
推荐阅读
- 霍格沃兹测试学院:内推 | 跳槽吗?可年前面试,年后入职的那种
- 「大咖说生活」你会怎么做?女子淡定回答被录取,面试官:看到男女同事抱在一起
- 「月影说职场」中专生答对被录用,面试官:1+1等于多少?4个大学生应聘失败
- 『数据库』4月数据库流行度排行:MySQL 成事实王者,国产openGauss引期待
- [面试]国培教育—2020江西公务员面试热点:生态菜“种”出致富路
- 【怪咖搞笑】幽默笑话:昨天去公司面试 碰到个美女面试官,原创
- 『怪咖搞笑』碰到个美女面试官,幽默笑话:昨天去公司面试
- 【鱼堂主爱思考】在办公室发现我牙齿上有菜叶,该怎么提醒才可以被录用,面试官问
- 【面试】Google 教你视频面试
- 『姵来晓晓看娱乐』并存入mysql数据库,超详细,python3快速爬取房源信息
