MST

星途 面试题库

面试题:MySQL临键锁机制中,如何避免幻读问题

在MySQL的事务场景下,简述临键锁机制是怎样避免幻读问题的,并举例说明幻读在未使用临键锁时可能出现的场景。
18.6万 热度难度
数据库MySQL

知识考点

AI 面试

面试题答案

一键面试

临键锁机制避免幻读问题原理

  1. 范围加锁:临键锁(Next-Key Lock)是行锁和间隙锁(Gap Lock)的组合。它会锁定某一行数据以及这一行数据前后的间隙。例如,表中有数据 id 为 1、3、5。当对 id = 3 的行加临键锁时,不仅会锁定 id = 3 这一行,还会锁定 (1, 3)(3, 5) 这两个间隙。
  2. 阻止插入:在事务场景下,当一个事务持有临键锁时,其他事务无法在被锁定的间隙中插入新数据。这就防止了在当前事务执行范围内新数据的插入,从而避免了幻读。因为幻读本质就是在同一事务的两次相同查询中,第二次查询看到了第一次查询之后其他事务插入的新数据。

未使用临键锁时幻读可能出现的场景

假设有一张 students 表,结构如下:

CREATE TABLE students (
    id INT PRIMARY KEY,
    name VARCHAR(50)
);

表中已有数据:

INSERT INTO students (id, name) VALUES (1, 'Alice'), (3, 'Bob');

事务1

START TRANSACTION;
-- 查询 id 大于 1 的学生
SELECT * FROM students WHERE id > 1;
-- 这里假设查询结果为 id = 3 的 Bob
-- 此时事务1未提交

事务2

START TRANSACTION;
-- 插入一条新数据
INSERT INTO students (id, name) VALUES (2, 'Charlie');
COMMIT;

事务1

-- 再次执行相同查询
SELECT * FROM students WHERE id > 1;
-- 此时查询结果除了 Bob,还出现了 Charlie,这就是幻读
COMMIT;

在上述场景中,如果使用临键锁,事务1在第一次查询 id > 1 时,会对 (1, +∞) 这个范围加临键锁,事务2在插入 id = 2 的数据时,由于 (1, 3) 间隙被锁定,插入操作会被阻塞,直到事务1提交或回滚,从而避免了幻读的发生。