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

MySQL中FOR UPDATE锁是否允许其他连接执行普通SELECT语句查询?

关于MySQL SELECT ... FOR UPDATE加锁后普通SELECT是否可读取的问题解答

问题1:未显式开启事务的普通SELECT能否读取被FOR UPDATE加锁的记录?

默认配置下(InnoDB引擎,事务隔离级别为可重复读RR/读提交RC),完全可以读取,不会被阻塞。
原因是InnoDB的普通无锁SELECT默认属于快照读,基于MVCC(多版本并发控制)机制实现,只会读取记录在undo log中保存的历史版本,不会申请读取目标行的锁资源,所以完全不会和其他事务持有的FOR UPDATE排他锁产生冲突。

问题2:“默认隐式事务下普通SELECT无法读取被FOR UPDATE锁定的记录”这一结论是否正确?

该结论错误,属于对隐式事务和InnoDB读逻辑的混淆。
首先明确两个核心概念:

  • 隐式事务的生效范围:仅针对需要加锁的当前读操作生效,包括SELECT ... FOR UPDATE、SELECT ... LOCK IN SHARE MODE、INSERT、UPDATE、DELETE等,这类操作需要读取记录的最新版本,并且需要申请对应锁资源,才会触发锁冲突阻塞。
  • 普通SELECT属于快照读,不涉及锁申请逻辑,和是否为隐式事务没有关联,无论是否显式开启事务,都不会被其他事务的FOR UPDATE锁阻塞。

唯一例外场景

只有当事务隔离级别调整为**串行化(SERIALIZABLE)**时,InnoDB会自动将普通无锁SELECT转换为SELECT ... LOCK IN SHARE MODE的共享锁当前读,这种场景下普通SELECT才会被其他事务持有的FOR UPDATE排他锁阻塞,该配置不属于MySQL默认配置。

本地验证方法

你可以通过两个MySQL客户端快速验证结论:

  1. 客户端A执行加锁操作不提交:
START TRANSACTION;
-- 假设test表存在id=1的记录
SELECT * FROM test WHERE id = 1 FOR UPDATE;
  1. 客户端B直接执行普通查询:
SELECT * FROM test WHERE id = 1;

执行后可以直接拿到查询结果,不会出现阻塞。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 11:09:00