开往未来的列车|这是我见过最有用的Mysql面试题,面试了无数公司总结的( 二 )


而隔离性有4个隔离级别 , 分别是:
read uncommit 读未提交 , 可能会读到其他事务未提交的数据 , 也叫做脏读 。
用户本来应该读取到id=1的用户age应该是10 , 结果读取到了其他事务还没有提交的事务 , 结果读取结果age=20 , 这就是脏读 。
开往未来的列车|这是我见过最有用的Mysql面试题,面试了无数公司总结的read commit 读已提交 , 两次读取结果不一致 , 叫做不可重复读 。
不可重复读解决了脏读的问题 , 他只会读取已经提交的事务 。
用户开启事务读取id=1用户 , 查询到age=10 , 再次读取发现结果=20 , 在同一个事务里同一个查询读取到不同的结果叫做不可重复读 。
开往未来的列车|这是我见过最有用的Mysql面试题,面试了无数公司总结的repeatable read 可重复复读 , 这是mysql的默认级别 , 就是每次读取结果都一样 , 但是有可能产生幻读 。
serializable 串行 , 一般是不会使用的 , 他会给每一行读取的数据加锁 , 会导致大量超时和锁竞争的问题 。
6. 那ACID靠什么保证的呢?A原子性由undo log日志保证 , 它记录了需要回滚的日志信息 , 事务回滚时撤销已经执行成功的sql
C一致性一般由代码层面来保证
I隔离性由MVCC来保证
D持久性由内存+redo log来保证 , mysql修改数据同时在内存和redo log记录这次操作 , 事务提交的时候通过redo log刷盘 , 宕机的时候可以从redo log恢复
7. 那你说说什么是幻读 , 什么是MVCC?要说幻读 , 首先要了解MVCC , MVCC叫做多版本并发控制 , 实际上就是保存了数据在某个时间节点的快照 。
我们每行数实际上隐藏了两列 , 创建时间版本号 , 过期(删除)时间版本号 , 每开始一个新的事务 , 版本号都会自动递增 。
还是拿上面的user表举例子 , 假设我们插入两条数据 , 他们实际上应该长这样 。
开往未来的列车|这是我见过最有用的Mysql面试题,面试了无数公司总结的这时候假设小明去执行查询 , 此时current_version=3
select * from user where id<=3;同时 , 小红在这时候开启事务去修改id=1的记录 , current_version=4
update user set name='张三三' where id=1;执行成功后的结果是这样的
开往未来的列车|这是我见过最有用的Mysql面试题,面试了无数公司总结的如果这时候还有小黑在删除id=2的数据 , current_version=5 , 执行后结果是这样的 。
开往未来的列车|这是我见过最有用的Mysql面试题,面试了无数公司总结的由于MVCC的原理是查找创建版本小于或等于当前事务版本 , 删除版本为空或者大于当前事务版本 , 小明的真实的查询应该是这样
select * from user where id<=3 and create_version<=3 and (delete_version>3 or delete_version is null);所以小明最后查询到的id=1的名字还是'张三' , 并且id=2的记录也能查询到 。 这样做是为了保证事务读取的数据是在事务开始前就已经存在的 , 要么是事务自己插入或者修改的 。
明白MVCC原理 , 我们来说什么是幻读就简单多了 。 举一个常见的场景 , 用户注册时 , 我们先查询用户名是否存在 , 不存在就插入 , 假定用户名是唯一索引 。


推荐阅读