2020面试十几家大厂,我把人手都会的数据库事务相关内容总结了一下。

2020面试十几家大厂,我把人手都会的数据库事务相关内容总结了一下。
最新回答
风微甜

2026-07-30 10:36:02

数据库事务是保证数据库操作独立完整性的程序执行单元,其核心特性、隔离级别及调度机制是面试高频考点,以下为系统总结:

一、事务的核心特性
  • 定义:事务是数据库操作的基本单位,由一条或多条SQL语句组成,具有明确的开始与结束(提交或回滚)。
  • 特性:

    原子性(Atomicity):事务不可分割,要么全部执行成功,要么全部回滚。

    一致性(Consistency):事务执行前后数据库状态保持合法(如余额转移需总额不变)。

    隔离性(Isolation):并发事务间相互隔离,避免干扰(通过隔离级别实现)。

    持久性(Durability):事务提交后,结果永久保存,即使系统故障也不丢失。

二、事务隔离级别与问题

隔离级别从低到高分为四级,级别越高并发性越低但数据一致性越强:

  • 读未提交(Read Uncommitted):

    问题:允许脏读(事务A读取事务B未提交的修改,若B回滚则A读到无效数据)。

    示例:

    -- 事务B修改id=2的num为10(未提交)-- 事务A读取id=2的num,得到10(脏读)-- 事务B回滚,id=2的num恢复为100
  • 读已提交(Read Committed):

    改进:解决脏读,事务A只能读取事务B已提交的数据。

    问题:不可重复读(同一事务内多次读取结果不一致)。

    示例:

    -- 事务A第一次读取id=2的num,得到100-- 事务B修改id=2的num为10并提交-- 事务A第二次读取id=2的num,得到10(不可重复读)
  • 可重复读(Repeatable Read):

    改进:解决不可重复读,同一事务内多次读取结果一致。

    问题:幻读(其他事务插入新数据导致查询结果集变化)。

    示例:

    -- 事务A第一次查询id>2的记录,得到id=3(num=200)-- 事务B插入id=4(num=30)并提交-- 事务A第二次查询id>2的记录,仍只有id=3(无幻读?需结合MVCC机制)-- 若事务A执行更新(如set num=0 where id>2),则第二次查询会看到id=4(num=0),出现幻读

    MVCC机制:通过多版本并发控制实现可重复读,但对写操作(如UPDATE)无效,导致幻读。

  • 串行化(Serializable):

    改进:完全隔离,通过加锁强制事务串行执行,避免脏读、不可重复读、幻读。

    代价:性能最低,并发性差,仅用于高一致性要求的场景。

三、事务调度与可串行性
  • 调度:事务操作(读、写、加锁、解锁)的执行顺序。
  • 并发调度正确性:若并发调度结果与串行调度一致,则调度正确。
  • 可串行化:调度效果等价于某个串行调度,是并发控制的最高目标。
四、隔离级别选择策略
  • 业务场景驱动:

    高并发读:优先选择读已提交(如Oracle默认)或可重复读(如MySQL默认)。

    严格一致性:使用串行化,但需评估性能损失。

    无事务需求:考虑非事务引擎(如MySQL的MyISAM)。

  • 性能权衡:隔离级别越高,并发性越低,需根据业务容忍度选择。
五、面试常见问题延伸
  1. MySQL默认隔离级别为何是可重复读?

    避免不可重复读,同时通过MVCC和间隙锁(Gap Lock)部分解决幻读问题,平衡一致性与性能。

  2. 幻读与不可重复读的区别?

    不可重复读针对同一数据的修改(如UPDATE),幻读针对数据集的增减(如INSERT/DELETE)。

  3. 如何避免幻读?

    使用串行化隔离级别,或通过应用层逻辑(如乐观锁)控制。

  4. 事务的ACID特性如何实现?

    原子性:通过Undo Log实现回滚。

    持久性:通过Redo Log实现故障恢复。

    隔离性:通过锁机制或MVCC实现。

    一致性:由其他三个特性共同保证。

总结:事务隔离级别是数据库并发控制的核心,理解其原理及适用场景是面试关键。实际选择需结合业务需求、性能要求及数据库特性(如MySQL与Oracle的默认差异)综合评估。