1. 事务特性
ACID(原子性、一致性、隔离性、持久性)
2. 事务的隔离级别
读未提交:RU
读已提交:RC(Oracle)
可重复读:RR(MySQL)
串行化:S
3. 不同隔离级别都有哪些问题
脏读:一个事务读到另一个事务没有提交的数据
不可重复读:(由于其他事务的更新操作)开启事务后,多次读取到的结果不一致
幻读:(由于其他事物的插入操作),多次读取 数据量不一样
慢
==============================不可重复读==============================
4. MySQL如何解决不可重复读的问题
MVCC
Multiversion Concurrency Control,多版本并发控制(一条数据,允许在同一时刻,不同事务或线程对它进行修改)
多版本(一条数据的版本链)并发(场景)控制(控制:控制读取的结果)
版本链
undo log和mysql针对每行数据的隐藏字段(trx_id——事务id和上个版本的指针)
读视图:read view
min_id:最小事务id:26
max_id:最大事务id(全局的下一个事务id,101)
cur_trx_id:当前事务id,100
active_id_list:当前活跃事务列表,22,33,75
1. 比最小事务id小,肯定读
2. 比最大事务id大,肯定不读
3. 当前事务id,肯定读
4. 最小事务id < 事务id < 最大事务id时:
- 不在当前活跃事务列表时,肯定已经提交了,肯定读
- 在当前活跃事务列表时,此时还未提交,不读
此时,有人可能会问,为什么不直接用事务id,与当前活跃事务列表进行比较?最小事务id的作用是什么?
事务id与最小事务id进行比较的时间复杂度是O(1),与当前活跃事务列表进行比较的时间复杂度是O(n),可以提高查询效率
隔离级别的真正区别,在于生成read view生成的时机
5. 幻读
定义:两次查询到的数据量不一致(其他事务插入或者删除数据引起)
解决方案:不让它插入或删除
假设现在表中有id为:1,7,8,10的数据
select for update(间隙锁)where id = 6
next-key-lock 行锁 + 间隙锁(给id=6的加行锁,id为1-7之间的加间隙锁——id为1-7之间的不能插入)
MVCC解决幻读:你可以改,但是改了我不读
上面的方式:粗暴,我不让你改
MYSQL解决了(快照读下的)幻读
快照读和当前读的区别?
6. MySQL底层的数据存储
磁盘以数据页(一页16KB)存储的
操作数据时,加载数据页到buffer pool(内存中),通过undo log版本链控制可以读到哪些数据,通过redo log(物理日志)、bin log(二进制日志、逻辑日志)控制提交或回滚,mysql底层会进行异步刷盘操作