MySQL数据库中的事务在面试中的高频考点
截止到今天为止,有关于MySQL数据库方面的问题就给大家更新完毕了,主要是设计三个板块,分别书MysQL索引、锁和本期的事务,这三大块是面试中的高频考点,希望大家可以多看看课本。
1.什么是事务?
事务是数据库区别于文件系统的重要特性之一,事务可以一条非常简单的SQL语句组成,也可以由一组复杂的SQL语句组成,事务是访问并更新数据库中各种数据项的一个程序执行单元。在事务中的操作,要么都做修改,要么都不做,这就是事务的主要目的。
2.事务的特性有哪些?分别是怎么保证的?
回答:事务的四大特性分别是原子性、一致性、隔离性和持久性。
下面这段话摘自《MySQL技术内幕-InnoDB存储引擎》
原子性、一致性和持久性是通过数据库的redo log和undo log来完成。redo log称为重做日志,用来保证事务的原子性和持久性。undo log用来保证事务的一致性。而隔离性是通过锁实现的。【具体大家看书吧,书上比较详细。】
面试官可能会问三种日志的区别和作用。
redo log:恢复提交事务修改的页操作;通常是物理日志,记录的是页的物理修改操作。
uodo log:回滚记录到某个特定版本;通常是逻辑日志,根据每行记录进行记录。
bin log:用来进行Point-In-Time(PIT)的恢复及主从复制环境的建立。
这里面试官可能会接着问binlog和redolog的区别?
回答:
(1)重做日志是在InnoDB存储引擎层产生的,而二进制日志是在MySQL数据库上层产生的,二进制日志不仅仅针对InnoDB存储引擎,任何存储引擎都会产生二进制日志。
(2)两种日志的记录内容形式不同。二进制日志是一种逻辑日志,记录的是SQL语句;而InnoDB存储引擎层面的重做日志是物理格式日志,记录的是对于每个页的修改。
(3)写入磁盘的时间不同,二进制日志只在事务提交完成后进行一次写入,而redo log在事务进行中不断的写入。
3.事务的隔离级别有哪些?InnoDB存储引擎默认的是什么存储引擎?为什么?
回答:首先回答一些数据库中并发事务带来的问题
1.数据丢失
2.脏读
3.不可重复读
4.幻读
不同的隔离级别
分别可以解决并发事务产生的几个问题,对应如下:
未提交读(Read Uncommitted):在事务 A 读取数据时,事务 B 读取和修改数据加了共享锁。这种隔离级别,会导致脏读、不可重复读以及幻读。
已提交读(Read Committed):在事务 A 读取数据时增加了共享锁,一旦读取,立即释放锁,事务 B 读取修改数据时增加了行级排他锁,直到事务结束才释放锁。也就是说,事务 A 在读取数据时,事务 B 只能读取数据,不能修改。当事务 A 读取到数据后,事务 B才能修改。这种隔离级别,可以避免脏读,但依然存在不可重复读以及幻读的问题。
可重复读(Repeatable Read):在事务 A 读取数据时增加了共享锁,事务结束,才释放锁,事务 B 读取修改数据时增加了行级排他锁,直到事务结束才释放锁。也就是说,事务A 在没有结束事务时,事务 B 只能读取数据,不能修改。当事务 A 结束事务,事务 B 才能修改。这种隔离级别,可以避免脏读、不可重复读,但依然存在幻读的问题。
可序列化(Serializable):在事务 A 读取数据时增加了共享锁,事务结束,才释放锁,事务 B 读取修改数据时增加了表级排他锁,直到事务结束才释放锁。可序列化解决了脏读、不可重复读、幻读等问题,但隔离级别越来越高的同时,并发性会越来越低。
建议:这块内容可以看一下《阿里调优手册》中的第33讲
MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读)
至于InnoDB为什么选用可重复读,我的个人理解是:在InnoDB存储引擎中,使用可重复读可以解决脏读、不可重复读,而幻读也有可能发生,但是是可以避免的,通过加Next-Key Lock锁可以解决幻读问题。并且并非隔离级别越高越好,隔离级别越高的话,并发性能越低,所以在实际的开发中,需要根据业务场景进行选择事务的隔离级别。
记得给个<stron>哦,你们的支持是我创作的最大动力,后续还会分析Redis相关的面试高频考点,敬请期待!</stron>
推荐阅读
#高频知识点汇总##学习路径#