前言
开始Mysql数据库面试知识的复习和资料的收集,本篇文章会不断更新,本系列文章主要分为两部分,一部分是该专题所涉及的相关基础知识,另一部分是面试题与思考题,大部分重要知识和基础知识的延伸会在面试题和思考题中给出,这样做的目的是给出具体的场景,便于理解知识(相较于直接在知识中展出),且我会以相对口语化的方式叙述。
建议关注,随着我复习的进度,内容会一直得到补充
事务相关知识
1.什么是事务
事务是一组操作的集合,一个不可分割的工作单位,事务会把所有操作作为一个整体一起向系统提交或撤销请求,这些操作要么同时成功,要么同时失败
2.事务操作(在mysql的sql语句中)
值得注意的是,Mysql默认的事务是自动提交,即执行完一条sql语句后就隐式提交了,所以在我们进行事务操作前,先将事务改成手动提交
查看事务提交方式(1表示自动提交,0表示手动提交)
SELECT @@autocommit;
设置事务提交方式为手动
SELECT @@autocommit=0;
提交事务
COMMIT;
回滚事务
ROLLBACK;
3.事务的四大特性-ACID
4.事务并发问题
脏读:读到了别的事务还没有提交的数据
例如:B事务要将从1000改为2000,但事务还没有提交,但A事务读取余额时为2000
不可重复读:连续读取同一条数据,但两次读取结果不一致
例如:事务A连续读取两次余额,第一次读取为1000,第二次读取之前,事务B将余额改为2000并提交了事务,此时A第二次读取就是2000,两次读取的结果不一致
幻读:连续查询符合某个条件的数据的数量,发现两次查询数量不一致
例如:事务A连续两次查询余额大于1000的人的个数,第一次查询出5人,第二次查询前,事务B新增了一个余额为2000的人并提交的事务,此时第二次查询出6人,两次查询数量不一致,发生了幻读
5.事务的隔离级别以及会发生哪些事务并发问题
从上到下依次为:读未提交,读已提交,可重复读(默认隔离级别),串行化
读未提交:指一个事务还没提交,他所做的更改就可以被其他事务看到
读已提交:指一个事务只有提交后,他所做的修改才能被其他事务看到
可重复读:指一个事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的
串行化:会对记录加上读写锁,在多个事务对这条记录进行读写操作时,串行进行
查看和修改数据库的事务隔离级别:
常见面试题和思考题
1.事务的四大特性是什么,InnoDB是通过什么技术来保证这四个特性的?
四大特性分别是原子性,持久性,隔离性,一致性,其中原子性是通过undo log回滚日志来保证的,持久性是通过redo log重做日志进行保证的,隔离性是通过MVCC多版本并发控制或锁机制,而一致性是通过原子性,隔离性,持久性来保证的(这里涉及到日志,我之后会更新该专题)
2.事务的隔离级别有哪些,那他们都是如何工作(实现)的?
隔离级别有:读未提交,读已提交,可重复读,串行化,其中可重复读是MySQL默认的事务隔离级别
读未提交因为可以读取别的事务没有提交的数据,所以直接读取最新数据即可
串行化是通过加锁的方式避免事务并行访问
而读已提交和读未提交是通过Read View来实现的
3.讲一讲你对Read View的理解,读已提交和读未提交对其应用有何不同?
Read View可以理解为一种数据快照,就像照片一样,用来记录某一时刻的状态,包含四个部分:
m_ids :指创建该read view时当前数据库中那些启动了但还没有提交的活跃事务的事务id列表
min_trx_id :指那些启动了但还没有提交的活跃事务的事务id列表中的最小id值
max_trx_id :指创建该read view时,如果此时mysql再新建一个事务,那个事务的id值,也就是当前最大id+1
creator_trx_id :创建该read view的事务的事务id
此外,mysql的每条数据处理我们自己定义的字段其实还有两个额外的字段,分别是:
trx_id:用来记录对该该条数据进行了修改的事务id
roll_pointer:当一个事务对当前数据进行修改时,会将旧数据存到undo log日志中,然后该字段是一个指针,指向旧记录在undo log中的位置
现在,我们就可以来看看读已提交和可重复读了:
可重复读:在启动事务时生成一个readview直到结束事务
举个例子:事务5开启后,生成了readview,其中readview中的数据为:活跃数据列表:2,3,活跃数据列表中的最小事务id:2,下一个事务id:7,当前事务id:5
假如我现在执行操作:查找小明的账户余额,当查到小明这条数据的时候,会先去看trx_id,假设是8,大于下一个事务id7,表示对该条记录进行修改的最后一个事务是在创建该readview之后创建的,所以该条记录读不到,那么就会沿着版本控制链去查旧的记录,例如图示如下:
查到旧纪录的trx_id是3,3在活跃列表中,表示当前活跃但未提交的事务,所以读不到,接着再查上一条旧记录,查到4,4小于下一个事务id,且不在活跃列表id中,表示这个事务之前就已经创建按并且提交了,所以这条记录可以被读到
读已提交:其在事务中执行每一条语句前都会生成一个readview,然后其他理解同上
同时,上面也是Read View在MVCC如何工作的
后言
持续更新~~~~~~~