当前位置: 首页 > 图灵资讯 > java面试题> 金三银四精选java面试题-MySQL的行级锁锁的是什么?

金三银四精选java面试题-MySQL的行级锁锁的是什么?

来源:图灵教育
时间:2023-12-05 10:24:12
 

MySQL的行级锁锁的是什么?

MySQL 中行级锁可以根据锁粒度的不同分成三种

  • 针对单个数据行进行加锁,称为记录锁
  • 针对数据行的间隙进行加锁,称为间隙锁
  • 记录锁和间隙锁的结合,锁定当前记录行与下一条记录行之间的间隙,称为临健锁

拓展:

drop TABLE orders;
CREATE TABLE orders (
    order_id INT NOT NULL PRIMARY KEY,
    product_name VARCHAR(50) NOT NULL,
    quantity INT NOT NULL
)  ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO orders (
	order_id,
	product_name,
	quantity
)
VALUES
	(1, 'iPhone', 2),
	(2, 'iPad', 1),
	(3, 'MacBook', 3),
	(7, 'AirPods', 7),
	(10, 'Apple Watch', 10);
  • 记录锁(Record Lock):记录锁是针对单个数据行进行加锁,防止其他事务修改。

当一个事务获取了某一行的记录锁后,其他事务无法同时获取该行的记录锁,记录锁只会影响到正在操作的行,不会阻塞其他事务对其他行的写操作。

例如:SELECT * FROM orders WHERE order_id = 2 FOR UPDATE;

order_id = 2 的这条记录会进行加锁,防止其他事务针对该记录进行删改。

  • 间隙锁(Gap Lock):间隙锁是用于保护一个数据范围的锁机制,它会在索引范围内的间隙(两个索引值之间)上设置锁。

当一个事务获取了间隙锁后,其他事务无法在该区间内插入新的数据行,主要用于防止幻读(Phantom Read)的情况发生。

例如:SELECT * FROM orders WHERE order_id = 8 FOR UPDATE;

由于 orders 表中不存在 order_id = 8 的记录,会将区间 (7,10) 进行加锁防止其他事务在这个区间进行增删改。

  • 临健锁(Next-Key Lock):临健锁是结合了记录锁和间隙锁的特性,用于保护一个数据范围的间隙和索引上的数据行。

它会在索引范围内的间隙和索引上的数据行上设置锁,解决了幻读和间隙插入的问题

例如:SELECT * FROM orders WHERE order_id >= 3 and order_id < 7 FOR UPDATE;

该 SQL 将锁定 [3,7) 这个区间防止其他事务针对该记录进行增删改。

需要注意间隙锁与临健锁,只在 InnoDb 的 RR 隔离级别下生效。