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

为何REPEATABLE READ隔离级别无法读取新插入行?

嘿,我来帮你捋清楚这里的问题哈!

核心问题:你没有真正实现并发执行事务

你现在把两个事务写在同一个查询脚本里,它们是按顺序串行执行的,根本没有达到“并发验证隔离级别”的目的——这就是结果和预期不符的关键原因!

要测试REPEATABLE READ隔离级别的效果,必须在两个独立的数据库会话(比如SSMS的两个查询标签页、或者两个终端窗口)分别运行对应的事务步骤,让它们真正并行起来。

正确的并发测试步骤(以SQL Server为例)

我给你拆解成清晰的步骤,你照着做就能看到REPEATABLE READ的真实效果:

1. 先初始化测试环境

随便打开一个会话(比如查询窗口1),执行以下脚本:

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
CREATE TABLE testLocking(a int);

2. 启动第一个事务(会话A)

在会话A(查询窗口1)里运行:

BEGIN TRANSACTION;
INSERT INTO testLocking VALUES (1);
SELECT * FROM testLocking; -- 这里会返回:1
WAITFOR DELAY '000:00:30'; -- 暂停30秒,给另一个会话留操作时间
SELECT * FROM testLocking; -- 这是事务内的第二次查询
COMMIT TRANSACTION;

运行后,会话A会进入30秒的等待状态,这时候赶紧切换到第二个会话。

3. 启动第二个并发事务(会话B)

立刻打开另一个会话(查询窗口2),运行:

BEGIN TRANSACTION;
INSERT INTO testLocking VALUES (2);
UPDATE testLocking SET a=4 WHERE a=1;
SELECT * FROM testLocking; -- 这里会话B会返回:4、2
WAITFOR DELAY '000:00:40';
COMMIT TRANSACTION;

4. 观察会话A的第二次查询结果

等会话A的30秒等待结束后,你会看到它的第二个SELECT仍然返回1——这正是REPEATABLE READ的核心特性:

  • 事务启动后会建立一个一致性读快照,在事务提交前,所有查询都会基于这个快照返回数据,看不到其他事务在这段时间插入或修改的新数据(这就是“可重复读”的含义:同一个事务内多次读同一数据集,结果完全一致)
  • 会话B的插入和更新操作不会被阻塞,但这些变更对会话A来说是不可见的,直到会话A自己提交事务。
关于你预期结果的误解

你预期的1、1、2、2、4其实混淆了不同会话的查询结果:

  • 会话A的两次查询只会返回1(受REPEATABLE READ隔离级别保护,看不到其他事务的变更)
  • 会话B自己的查询会返回4、2(它自己的变更在当前事务内是可见的)

最后记得清理环境,任意会话执行:

DROP TABLE testLocking;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:41:07