数据库事务与隔离级别

返回 面试 · 速查全集 数据库常见面试题

事务是一组 SQL 的逻辑单元:要么全部提交,要么全部回滚。详解 数据库事务


ACID

特性含义InnoDB 实现
A 原子性全成功或全回滚undo log
C 一致性数据满足约束与业务规则A+I+D + 约束
I 隔离性并发事务互不干扰MVCC + 锁
D 持久性提交后宕机不丢redo log(WAL)

并发读问题

问题描述哪级隔离能防
脏读读到别的事务未提交的数据RC 及以上
不可重复读同事务两次读同一行,结果不同RR 及以上
幻读同事务两次范围查询,行数不同Serializable;MySQL RR+间隙锁大部分防
丢失更新两事务读-改-写,后者覆盖前者乐观锁 / FOR UPDATE

四种隔离级别

级别脏读不可重复读幻读说明
READ UNCOMMITTED几乎不用
READ COMMITTEDOracle 默认;每次读新快照
REPEATABLE READ⚠️MySQL InnoDB 默认
SERIALIZABLE串行,性能差
SELECT @@transaction_isolation;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

MVCC(快照读)

InnoDB 通过 多版本 + ReadView 让普通 SELECT 不加锁(快照读),提高并发。

当前行 (trx_id=100)
    ↓ undo 链
  trx_id=80 → trx_id=50 → ...

ReadView 记录活跃事务 ID,按规则判断版本是否对当前事务可见。

隔离级别ReadView 时机
RC每次 SELECT 新建
RR事务第一次读时创建,之后复用

当前读UPDATE / DELETE / SELECT ... FOR UPDATE)走锁,不走 MVCC 快照。


锁与幻读(RR)

作用
行锁锁索引记录
间隙锁锁记录间空隙,防插入
Next-Key Lock行锁 + 间隙锁(RR 默认)

因此 MySQL RR 下「幻读」在 InnoDB 里大部分被抑制(面试常考与标准教科书的差异)。


Spring 事务 vs 数据库事务

层次作用
数据库单 Connection 上的 ACID
@TransactionalAOP 管理何时 begin/commit/rollback

传播行为 REQUIREDREQUIRES_NEW 等见 Spring @Transactional 传播行为;失效场景见 SpringBoot事务失效场景


常见面试题

Q:只设置了 RR,为什么还会幻读?
A:标准定义下 RR 仍可能幻读;InnoDB 用间隙锁在当前读场景防插入;纯快照读看到的是固定版本,不存在「新行插入进快照」的幻读表现。

Q:RC 和 RR 怎么选?
A:要读最新已提交数据用 RC(Oracle 风格);要同事务内 repeatable 读用 RR(MySQL 默认)。

Q:长事务有什么危害?
A:undo 链变长、锁持有久、死锁概率升、主从延迟;事务内勿做 HTTP/MQ。


相关笔记