Files
examination/topics/database/mysql-transaction-isolation/short_answer.json
T
wonder 515acbcc7f
Deploy Examination / deploy (push) Successful in 4s
feat: add database topic group with 105 questions
- mysql-acid (35): undo/redo log, WAL, 崩溃恢复三阶段, 两阶段提交
- mysql-transaction-isolation (35): 四隔离级别, 三异常, Read View, 快照读/当前读, next-key lock
- redis-persistence (35): RDB/AOF/混合持久化, AOF 重写, vs binlog/redo log
- 每子主题: single_choice×10 + fill_blank×10 + short_answer×10 + code_reading×5
- 全部通过 question.schema.json 校验
2026-09-07 19:17:38 +08:00

213 lines
13 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"topic": "mysql-transaction-isolation",
"type": "short_answer",
"schema_version": "1.0.0",
"generated": "2026-09-07T00:00:00+08:00",
"questions": [
{
"id": "sa-001",
"type": "short_answer",
"difficulty": 1,
"tags": [
"隔离级别"
],
"question": "请列出 MySQL InnoDB 支持的四种事务隔离级别,并按隔离强度从低到高说明它们的名称(中英文均可)。",
"answer": "四种隔离级别从低到高依次是:READ UNCOMMITTED(读未提交)、READ COMMITTED(读已提交)、REPEATABLE READ(可重复读,MySQL 默认)、SERIALIZABLE(串行化)。",
"keywords": [
"READ UNCOMMITTED",
"READ COMMITTED",
"REPEATABLE READ",
"SERIALIZABLE",
"默认"
],
"scoring_rubric": "正确列出四个名称各 2 分(共 8 分);答对从低到高顺序并指出 REPEATABLE READ 是 MySQL 默认级别得 2 分。",
"explanation": "四个隔离级别的强度递增:RU 最低允许脏读;RC 只读已提交但出现不可重复读;RR 额外用 MVCC 快照与间隙锁/临键锁防止幻读(MySQL InnoDB 默认);SERIALIZABLE 最高,所有读都加锁串行。"
},
{
"id": "sa-002",
"type": "short_answer",
"difficulty": 2,
"tags": [
"脏读",
"不可重复读",
"幻读"
],
"question": "请分别解释事务并发过程中出现的三个异常现象:脏读、不可重复读、幻读。",
"answer": "脏读:一个事务读到了另一个事务尚未提交(可能回滚)的数据。不可重复读:同一事务内,两次读取同一行数据得到不同的值,因为期间有其他事务修改并提交了该行。幻读:同一事务内,两次执行同一条件查询得到的行数不同,因为另一事务在期间插入或删除了满足条件的行(幻读主要由插入产生)。",
"keywords": [
"脏读",
"不可重复读",
"幻读",
"未提交",
"行数变化"
],
"scoring_rubric": "三个现象各 3 分,正确描述现象并点出各自关键特征(脏读=未提交、不可重复读=同一行值变化、幻读=行数变化)得满分;部分答对按要点给分。",
"explanation": "三者隔离强度递进:脏读最严重(连提交状态都不判断);不可重复读是同一行值变化;幻读是结果集行数变化。SERIALIZABLE 能杜绝全部三种;RR 靠快照读 + 间隙锁基本防住幻读;RC 会发生不可重复读。"
},
{
"id": "sa-003",
"type": "short_answer",
"difficulty": 3,
"tags": [
"隔离级别",
"脏读",
"不可重复读",
"幻读"
],
"question": "请分别说明四种隔离级别各自允许哪些并发异常(脏读、不可重复读、幻读)。",
"answer": "READ UNCOMMITTED:三种异常都可能出现(脏读、不可重复读、幻读)。READ COMMITTED:不允许脏读,但可能出现不可重复读;对幻读在 MySQL 的语义下基本不设防。REPEATABLE READ:不允许脏读与不可重复读,通过 MVCC 快照读与间隙锁/临键锁基本防止了幻读。SERIALIZABLE:三种异常都不允许,所有读都加锁,事务串行执行。",
"keywords": [
"脏读",
"不可重复读",
"幻读",
"各隔离级别",
"SERIALIZABLE"
],
"scoring_rubric": "每个级别正确描述其允许/禁止的异常得 2.5 分(共 10 分),需同时说对允许或禁止哪些现象。",
"explanation": "隔离级别由低到高允许的异常:RU 全允许;RC 除脏读外其余可发生;RR 基本不允许脏读和不可重复读,幻读由 MVCC+锁基本消除;SERIALIZABLE 全禁止。"
},
{
"id": "sa-004",
"type": "short_answer",
"difficulty": 3,
"tags": [
"MVCC",
"版本链",
"undo log"
],
"question": "简述 MySQL InnoDB 的 MVCC(多版本并发控制)是什么?它依赖哪些隐藏列形成版本链?有何作用?",
"answer": "MVCC 即多版本并发控制,核心思路是让普通 SELECT(快照读)通过读取历史版本与写操作并行且不互斥。每行会隐藏两个列:DB_TRX_ID(最后修改该行的事务 ID)和 DB_ROLL_PTR(指向 undo log 中旧版本的指针),多个历史版本通过 DB_ROLL_PTR 串成一条版本链。快照读依据 Read View 沿版本链找到对当前事务可见的那个版本。作用是实现读写不互斥,提高并发度,并支撑 RC 的读已提交与 RR 的可重复读。",
"keywords": [
"MVCC",
"DB_TRX_ID",
"DB_ROLL_PTR",
"版本链",
"undo log",
"读写不互斥"
],
"scoring_rubric": "说出 MVCC 使读写不互斥(2 分)、两个隐藏列 DB_TRX_ID/DB_ROLL_PTR(各 2 分)、版本链与 undo log(2 分)、讲清作用(2 分)。",
"explanation": "MVCC 是不加锁并发读的重要机制。undo log 保存旧版本,DB_ROLL_PTR 指向它们,从而把同一行的所有历史版本串成一条版本链。"
},
{
"id": "sa-005",
"type": "short_answer",
"difficulty": 4,
"tags": [
"Read View",
"版本链"
],
"question": "请描述 Read View 的四个核心字段,并用它们说明 MVCC 判断某行版本可见性的规则。",
"answer": "Read View 四个字段:m_ids(创建快照这一刻尚未提交的事务 ID 集合)、min_trx_id(m_ids 中最小的事务 ID)、max_trx_id(下一条将要分配的事务 ID 或最大事务 ID)、creator_trx_id(当前创建 ReadView 的事务自身 ID)。可见性判断顺序:一是版本 trx_id 等于 creator_trx_id(自己改的)则可见;二是 trx_id 小于 min_trx_id(该事务已提交且在快照前)则可见;三是 trx_id 大于等于 max_trx_id(快照之后才启动的事务)则不可见;四是 trx_id 处于 m_ids 集合中(尚未提交)则不可见;五是否则可见。若当前版本不可见,则沿 DB_ROLL_PTR 向版本链更旧版本回溯继续判断。",
"keywords": [
"m_ids",
"min_trx_id",
"max_trx_id",
"creator_trx_id",
"可见性"
],
"scoring_rubric": "正确写出四个字段各 1 分(共 4 分);可见性规则每条(自己可见、已提交可见、未提交不可见、新事务不可见)约 1.5 分,共约 6 分。",
"explanation": "ReadView 是 MVCC 可见性判断的核心,关键在于顺序判断:trx_id 小于 min 可见、大于等于 max 不可见、在 m_ids 中不可见。掌握它才能理解 RC 与 RR 的差异。"
},
{
"id": "sa-006",
"type": "short_answer",
"difficulty": 4,
"tags": [
"隔离级别",
"Read View"
],
"question": "为什么 READ COMMITTED 会发生不可重复读,而 REPEATABLE READ 不会?请从 Read View 的创建时机角度解释。",
"answer": "因为两者创建 ReadView 的时机不同。READ COMMITTED 下每执行一次普通 SELECT(快照读)都会新建一个 ReadView,因此后一次的 SELECT 能看到其他事务最新提交的数据,导致同一事务内两次读到不同值,即产生不可重复读。REPEATABLE READ 下,事务的第一条 SELECT 才创建 ReadView,之后整个事务内所有快照读都复用这一份 ReadView,其他事务的提交对这份固定快照不可见,因此多次读取结果一致,即满足可重复读。",
"keywords": [
"新 ReadView",
"复用",
"每次 SELECT",
"不可重复读"
],
"scoring_rubric": "指出 RC 每次都新建 ReadView(3 分)、RR 复用首次的 ReadView(3 分)、并正确连接到不可重复读与可重复读现象(4 分)。",
"explanation": "这正是 RC 与 RR 在 MVCC 上最本质的区别:ReadView 的创建时机与复用策略决定了可见版本集合的刷新频率。"
},
{
"id": "sa-007",
"type": "short_answer",
"difficulty": 3,
"tags": [
"快照读",
"当前读"
],
"question": "请解释 MySQL 中快照读与当前读的区别,并各举一个例子。",
"answer": "快照读(Snapshot Read,也称一致性非锁定读):普通的 SELECT,不加任何锁,通过 MVCC 读取一致性快照(依据 ReadView),不会因其它事务的写操作而阻塞。例子:SELECT * FROM t(不带 FOR UPDATE 或 LOCK IN SHARE MODE)。当前读(Current Read):读取数据的最新已提交版本,并在读取后被访问的影响记录加锁,属于加锁读。例子:SELECT ... FOR UPDATE(排X锁)、SELECT ... LOCK IN SHARE MODE(共享锁),以及 UPDATE、DELETE、INSERT 语句本身就是当前读。核心区别:快照读走 MVCC 不加锁,当前读走锁、读最新提交数据。",
"keywords": [
"快照读",
"当前读",
"MVCC",
"加锁",
"FOR UPDATE"
],
"scoring_rubric": "将快照读解释为 MVCC 不加锁(3 分)、当前读解释为加锁读最新(3 分)、各举正确例子(4 分)。",
"explanation": "快照读与当前读是理解 MySQL 并发读与锁行为的关键。注意 UPDATE/DELETE/INSERT 必须读最新提交并加锁,避免基于旧数据覆盖。"
},
{
"id": "sa-008",
"type": "short_answer",
"difficulty": 4,
"tags": [
"临键锁",
"间隙锁",
"行锁",
"幻读"
],
"question": "解释 Record Lock、Gap Lock、Next-Key Lock 三者的区别,以及它们如何配合防止幻读。",
"answer": "Record Lock(行锁):只锁定某一条具体记录,阻止对该行的修改。Gap Lock(间隙锁):锁定某个索引区间内的空隙(不含已存在的记录),阻止其他事务在这个空隙内插入新行,但它本身不保护具体记录,且间隙锁之间通常不互相排斥。Next-Key Lock(临键锁):是 Record Lock 与 Gap Lock 的组合,防护左开右闭区间,同时锁定记录本身及其之前的间隙。防幻读机制:REPEATABLE READ 下的当前读(如 SELECT ... FOR UPDATE、UPDATE、DELETE)会加 Next-Key 锁,把范围内所有可能插入的位置锁住,从而阻止并发事务插入新行,避免出现幻行。",
"keywords": [
"Record Lock",
"Gap Lock",
"Next-Key Lock",
"防幻读",
"间隙"
],
"scoring_rubric": "分别描述三种锁的特征各 2 分(共 6 分);解释临键锁如何通过间隙锁阻止插入防幻方 4 分。",
"explanation": "Next-Key Lock 等于 Record Lock 加 Gap Lock,是 RR 下当前读防幻读的关键。间隙锁专为堵插入而设计。"
},
{
"id": "sa-009",
"type": "short_answer",
"difficulty": 2,
"tags": [
"隔离级别"
],
"question": "如果业务需要最严格的隔离保证(不允许脏读、不可重复读、幻读),你会选择哪个隔离级别?代价是什么?",
"answer": "选择 SERIALIZABLE(串行化)。它是最高隔离级别,会强制将所有普通 SELECT 也转为加锁读(等价于给读取范围加共享锁并配合临键锁/间隙锁),读写完全互斥、事务近乎串行,从而杜绝脏读、不可重复读和幻读。代价是并发度大幅下降,读操作之间也互斥,容易引发锁竞争、阻塞甚至死锁,吞吐量明显低于其他级别;因此若非必要一般不直接使用,可在业务层用更精细的锁或优化 SQL 替代。",
"keywords": [
"SERIALIZABLE",
"串行化",
"加锁读",
"并发下降",
"代价"
],
"scoring_rubric": "答对选择 SERIALIZABLE(3 分);说明其加锁机制保证全隔离(3 分);指出以并发与性能为代价(4 分)。",
"explanation": "SERIALIZABLE 是安全但昂贵的:全部读都加锁,牺牲了 MVCC 的读写并发优势,只适合极苛刻场景。"
},
{
"id": "sa-010",
"type": "short_answer",
"difficulty": 3,
"tags": [
"MVCC",
"隔离级别",
"快照读"
],
"question": "InnoDB 的 MVCC 为什么在 READ COMMITTED 与 REPEATABLE READ 下都能工作?两者基于 MVCC 提供的可读行为有何区别?",
"answer": "MVCC 是 InnoDB 中通过每行版本链(DB_TRX_ID + DB_ROLL_PTR)与 Read View 判断可见性的通用机制,因此在 RC 与 RR 两个隔离级别下都会启用 MVCC。行为区别:RC 每次普通 SELECT 新建 ReadView,能读其他事务最新已提交的版本,产生不可重复读;RR 在事务第一条 SELECT 建立 ReadView 并全程复用,因此整个事务内快照一致,满足可重复读。两者 MVCC 基础设施相同,但 ReadView 的创建/复用规则不同,导致对外行为不同。",
"keywords": [
"MVCC",
"ReadView",
"RC 每次",
"RR 复用",
"可重复读"
],
"scoring_rubric": "说明 MVCC 在两个级别均启用(3 分);RC 每次新建 ReadView 的行为(3 分);RR 每次复用 ReadView 的行为(4 分)。",
"explanation": "MVCC 是基础,真正区分 RC/RR 语义的是 ReadView 的创建时机与复用策略,理解这点就掌握了 MySQL 并发读的核心。"
}
]
}