面试官:你说对 MySQL 事务很熟?那我问你 10 个问题( 二 )


面试官:你说对 MySQL 事务很熟?那我问你 10 个问题

文章插图
脏读
不可重复读
一个事务内在读取某些数据后的某个时间,再次读取以前读过的数据,却发现其读出的数据已经发生了变更、或者某些记录已经被删除了 。
面试官:你说对 MySQL 事务很熟?那我问你 10 个问题

文章插图
不可重复读
幻读
事务A在按查询条件读取某个范围的记录时,事务B又在该范围内插入了新的满足条件的记录,当事务A再次按条件查询记录时,会产生新的满足条件的记录(幻行 Phantom Row)
面试官:你说对 MySQL 事务很熟?那我问你 10 个问题

文章插图
幻读
不可重复读与幻读有什么区别?
  • 不可重复读的重点是修改:在同一事务中,同样的条件,第一次读的数据和第二次读的「数据不一样」 。(因为中间有其他事务提交了修改)
  • 幻读的重点在于新增或者删除:在同一事务中,同样的条件,第一次和第二次读出来的「记录数不一样」 。(因为中间有其他事务提交了插入/删除)
四个隔离级别知道吗?解决了什么问题SQL实现了四个标准的隔离级别,每一种级别都规定了一个事务中所做的修改,哪些在事务内和事务间是可见的,哪些是不可见的 。低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销 。
面试官:你说对 MySQL 事务很熟?那我问你 10 个问题

文章插图
隔离级别
各个隔离级别可以不同程度的解决脏读、不可重复读、幻读 。隔离级别各有所长,没有完美的解决方案,脱离业务场景谈具体实施都是耍流氓 。
面试官:你说对 MySQL 事务很熟?那我问你 10 个问题

文章插图
隔离级别对比
MySQL中哪些存储引擎支持事务?
MySQL中InnoDB和NDB Cluster存储引擎提供了事务处理能力,以及其他支持事务的第三引擎 。
什么是自动提交?
MySQL默认采用自动提交AUTOCOMMIT模式 。也就是说,如果不是显式地开始一个事务,则每个查询都被当作一个事务执行提交操作 。
对于MyISAM或者内存表这些事务型的表,修改AUTOCOMMIT不会有任何影响 。对这类表来说,没有COMMIT或者ROLLBACK的概念,也可以说是相当于一直处于AUTOCOMMIT启用的模式 。
在事务中可以混合使用存储引擎吗?
尽量不要在同一个事务中使用多种存储引擎,MySQL服务器层不管理事务,事务是由下层的存储引擎实现的 。
如果在事务中混合使用了事务型和非事务型的表(例如InnoDB和MyISAM表),在正常提交的情况下不会有什么问题 。
但如果该事务需要回滚,非事务型的表上的变更就无法撤销,这会导致数据库处于不一致的状态,这种情况很难修复,事务的最终结果将无法确定 。所以,为每张表选择合适的存储引擎非常重要 。
MySQL存储引擎类型有哪些?
最常用的存储引擎是InnoDB引擎和MyISAM存储引擎,InnoDB是MySQL的默认事务引擎 。
【面试官:你说对 MySQL 事务很熟?那我问你 10 个问题】查看数据库表当前支持的引擎 :
showtablestatusfrom'your_db_name'wherename= 'your_table_name';
查询结果表中的`Engine`字段指示存储引擎类型 。
InnoDB存储引擎的特点和应用场景?
InnoDB是MySQL的默认「事务引擎」,被设置用来处理大量短期(short-lived)事务,短期事务大部分情况是正常提交的,很少会回滚 。
更多InnoDB事务模型相关,参考MySQL官方手册,这里贴一下链接:https://dev.mysql.com/doc/refman/5.7/en/innodb-transaction-model.html
历史
现代MySQL版本中的InnoDB在历史上叫InnoDB plugin,这个MySQL插件在2008年被开发出来,直到2010在Oracle收购了Sun公司后,发布的MySQL5.5才正式使用InnoDB plugin替代了旧版本的InnoDB,至此 「备胎」成功转正成为MySQL的御用引擎而不再是插件,你看一个插件都这么努力 。
特点
采用多版本并发控制(MVCC,MultiVersion Concurrency Control)来支持高并发 。并且实现了四个标准的隔离级别,通过间隙锁next-key locking策略防止幻读的出现 。
引擎的表基于聚簇索引建立,聚簇索引对主键查询有很高的性能 。不过它的二级索引secondary index非主键索引中必须包含主键列,所以如果主键列很大的话,其他的所有索引都会很大 。因此,若表上的索引较多的话,主键应当尽可能的小 。另外InnoDB的存储格式是平台独立 。
InnoDB做了很多优化,比如:磁盘读取数据方式采用的可预测性预读、自动在内存中创建hash索引以加速读操作的自适应哈希索引(adaptive hash index),以及能够加速插入操作的插入缓冲区(insert buffer)等 。


推荐阅读