You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL5.7 InnoDB下select与update访问同记录的锁机制问题咨询

MySQL 5.7 InnoDB 锁行为场景解答

以下结论基于MySQL 5.7 默认参数配置的InnoDB引擎,默认隔离级别为可重复读(REPEATABLE READ),默认开启MVCC(多版本并发控制),所有提到的select均为普通无锁查询,更新操作均为题目描述的基于主键的精准更新。

场景1:读操作执行过程中并发更新同一条记录

  • 结论:两个操作无需互相等待,可以正常并发执行。
  • 锁机制具体表现:
    1. InnoDB的普通select属于快照读,不会对数据加任何行锁/表锁,而是通过读取undo log中存储的历史版本数据来获取一致性结果。
    2. 执行update的线程只会给目标行加X型排他行锁,这类锁仅会阻塞其他需要加锁的操作(比如其他针对同一行的update/delete、select ... for update/select ... lock in share mode),不会阻塞普通快照读。
    3. 读线程不会感知到更新线程加的行锁,直接读取历史版本即可,更新线程也不会被读操作阻塞,拿到行锁后即可完成字段更新。

场景2:批量更新执行过程中并发查询同一条记录

  • 结论:默认配置下两个操作无需互相等待,可以正常并发执行。
  • 锁机制具体表现:
    1. 批量更新线程基于主键定位需要修改的10000条记录,会逐行给目标行加X型排他行锁,更新完成后生成新的数据版本,修改前的旧版本会保留在undo log中。
    2. 执行select的线程依旧走MVCC快照读逻辑,不需要申请任何数据锁,会根据自身事务的一致性视图从undo log中读取匹配的历史版本数据:如果select事务启动在批量更新事务提交前,就会读到更新前的字段值;如果启动在批量更新事务提交后,就会读到更新后的null值。
    3. 仅当select为加锁读时,才会等待批量更新线程释放对应行的X锁,出现阻塞等待的情况。

补充说明

因为更新操作是基于主键执行的精准匹配,不会出现全表扫描的情况,InnoDB只会给实际需要更新的行加行锁,不会加gap锁(间隙锁)也不会锁全表,不会影响该表其他行的读写操作。


内容的提问来源于stack exchange,提问作者jithin giri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 08:18:04