MySQL的UPDATE语句会加哪些锁?

低功耗蓝牙项目,需要一块懂省电的板

思澈 SF32LB52 芯片,BLE 协议栈深度优化,上手即开发

MySQL UPDATE 语句加锁机制解析(基于 InnoDB 引擎)


1. UPDATE 语句涉及的锁类型

在 InnoDB 存储引擎中,UPDATE 语句主要涉及以下几种锁:

锁类型作用范围作用说明
行锁(Record Lock)具体的行锁住被 UPDATE 修改的行,防止其他事务修改该行。
间隙锁(Gap Lock)行记录之间的索引区间锁住查询范围内的“间隙”,防止其他事务插入新记录(仅 REPEATABLE READ 级别会用到)。
临键锁(Next-Key Lock)行锁 + 间隙锁REPEATABLE READ 级别下默认行为,锁住索引记录及其间隙,防止幻读。
意向排他锁(IX Lock)整张表表示事务即将在某些行上加 X 锁,不会阻塞其他事务的行级锁,但会影响表级锁。

2. UPDATE 语句的加锁细节

(1)单行更新

UPDATE user SET age = 30 WHERE id = 1;

加锁行为:

  • 行锁(Record Lock):锁住 id=1 这行,防止其他事务修改。

  • 意向排他锁(IX):在 user 表上添加 IX 锁,不会影响其他事务查询和更新不同的行。

示例:

  • 事务A:

    START TRANSACTION;
    UPDATE user SET age = 30 WHERE id = 1;
    -- 事务A锁住了 id=1 这一行
    
  • 事务B(尝试更新相同的行,阻塞):

    UPDATE user SET age = 40 WHERE id = 1;
    -- 事务A未提交时,事务B会被阻塞
    

(2)范围更新(WHERE 条件命中多行)

UPDATE user SET age = 30 WHERE age > 20;

加锁行为(REPEATABLE READ 级别)

  • 行锁(Record Lock):锁住所有 age > 20 的记录。

  • 间隙锁(Gap Lock):锁住 age=20 之后的索引区间,防止其他事务插入新行。

  • 临键锁(Next-Key Lock)(默认开启):

    • 既锁住已有的行,也锁住 age > 20 之间的间隙,防止幻读

    • 如果事务 B 试图插入 age=25,会被阻塞。


(3)无索引条件更新

UPDATE user SET age = 30 WHERE name = 'Alice';

加锁行为(InnoDB 无合适索引时)

  • 全表扫描:MySQL 需要扫描整张表找 name='Alice',导致行锁升级为表锁

  • 表锁(Table Lock):阻塞所有对该表的写操作,极大降低并发性能。

优化方案

ALTER TABLE user ADD INDEX idx_name (name);

加索引后,只锁 name='Alice' 的记录,而不是整张表。


3. 不同隔离级别对 UPDATE 加锁的影响

隔离级别行锁间隙锁Next-Key Lock
READ UNCOMMITTED
READ COMMITTED
REPEATABLE READ(默认)
SERIALIZABLE✅(甚至可能升级为表锁)
  • READ COMMITTED:仅对实际匹配的行加行锁,不会加间隙锁,不会防止幻读。

  • REPEATABLE READ:默认使用 Next-Key Lock(行锁+间隙锁),可防止幻读。

  • SERIALIZABLE:可能升级为表级锁,完全阻止并发写入。


4. 死锁风险

当两个事务同时更新不同的记录时,如果获取锁的顺序不同,可能发生死锁。

示例:

-- 事务 A
START TRANSACTION;
UPDATE user SET age = 30 WHERE id = 1;
UPDATE user SET age = 40 WHERE id = 2; -- 这里可能被事务 B 锁住

-- 事务 B(反向顺序)
START TRANSACTION;
UPDATE user SET age = 40 WHERE id = 2;
UPDATE user SET age = 30 WHERE id = 1; -- 这里可能被事务 A 锁住,形成死锁

解决方案:

  • 始终按照相同顺序更新记录

  • 合理使用索引,避免锁表

  • SHOW ENGINE INNODB STATUS 分析死锁


5. 关键总结

  • UPDATE 语句会加

    • 行锁(防止其他事务修改相同行)。

    • 间隙锁(防止插入,避免幻读)。

    • Next-Key Lock(行锁+间隙锁,REPEATABLE READ 默认)。

    • 意向排他锁(IX)(保证表锁和行锁协调)。

  • 索引影响加锁范围

    • 有索引时,只锁定命中的行

    • 无索引时,可能锁全表(导致性能下降)。

  • 不同隔离级别影响加锁策略

    • READ COMMITTED 仅加行锁,不加间隙锁。

    • REPEATABLE READ 默认启用 Next-Key Lock 以防止幻读。

  • 死锁处理

    • 事务必须按相同顺序更新数据,避免死锁。

    • 可使用 SHOW ENGINE INNODB STATUS 分析死锁原因。

这些机制确保 UPDATE 操作在高并发环境下既能保证一致性,又能尽量减少性能损耗。

低功耗蓝牙项目,需要一块懂省电的板

思澈 SF32LB52 芯片,BLE 协议栈深度优化,上手即开发

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值