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

为何带子查询的SELECT ... FOR UPDATE会创建快照,INSERT ... SELECT却不会?

MySQL InnoDB可重复读隔离级别下一致性快照(Read View)的创建时机问题

测试场景

测试使用两张表,表结构如下:

CREATE TABLE table1 (  
  name VARCHAR(100) NOT NULL,  
  INDEX idx_table1_name (name)  
);  

CREATE TABLE table2 (  
  name VARCHAR(100) NOT NULL,  
  INDEX idx_table2_name (name)  
);  

案例1:带子查询的SELECT ... FOR UPDATE

事务1执行:

START TRANSACTION;  
SELECT * FROM table1 
WHERE name = (
  SELECT name FROM table2 WHERE name = 'a'
) FOR UPDATE;

事务2执行:

START TRANSACTION;  
INSERT INTO table2 VALUES ('b');  
COMMIT;  

回到事务1执行:

SELECT * FROM table2 WHERE name = 'b';   
-- 返回空集

现象分析:该结果表明带子查询的SELECT ... FOR UPDATE执行时已创建一致性快照,因此无法看到事务2提交的新数据'b'。

案例2:带子查询的INSERT INTO ... SELECT

事务1执行:

START TRANSACTION;   
INSERT INTO table1    
SELECT 'c' FROM table2 WHERE name = 'a';  

事务2执行:

START TRANSACTION;  
INSERT INTO table2 VALUES ('b');  
COMMIT;  

回到事务1执行:

SELECT * FROM table2 WHERE name = 'b';  
-- 返回'b'

现象分析:该结果说明INSERT INTO ... SELECT未创建一致性快照,能够看到事务2提交的新数据。根据官方文档,常规SELECT ... FOR UPDATE属于DML操作而非普通查询。

问题

  • 为何带子查询的SELECT ... FOR UPDATE会创建快照?
  • 为何同处于可重复读隔离级别,INSERT INTO ... SELECT却不创建快照?
  • 该行为是否在MySQL官方文档中有记载?
  • 快照的创建时机是否取决于DML中是否存在子查询?

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 18:04:53