Azure SQL Server启用RCSI仍出现脏读问题求助
RCSI开启后事务内读未提交数据的原因解析
你遇到的现象并非脏读,而是SQL Server的默认事务内行为,核心原因如下:
RCSI的作用范围是跨事务的读操作:READ_COMMITTED_SNAPSHOT开启后,不同事务之间的读请求会读取数据的版本化快照(已提交的数据),避免读取其他事务未提交的修改。但同一个事务内的读操作,默认会直接看到自身未提交的修改,这不属于脏读范畴(脏读特指读取其他事务未提交的数据)。
你的测试代码逻辑问题:
你在同一个事务内先执行INSERT,紧接着执行的SELECT属于当前事务的一部分,SQL Server会直接返回当前事务内已修改但未提交的数据,所以NoHint返回2是正常行为,并非RCSI失效。
正确验证RCSI的方法
要验证RCSI是否生效,需要使用两个独立的会话:
- 会话1:
BEGIN TRANSACTION; INSERT INTO [dbo].[IncTesting5] ([random_string]) VALUES ('UncommittedRow1'),('UncommittedRow2'); -- 不要提交或回滚,保持事务打开 - 会话2:
此时会话2的查询会返回0(事务开始前的已提交数据),这才是RCSI生效的表现。SELECT COUNT([random_string]) FROM [dbo].[IncTesting5];
额外说明
- 即使在同一个事务内使用
WITH(READUNCOMMITTED)提示,依然会读取到自身未提交的修改,这个提示主要影响跨事务的读行为,允许读取其他事务的未提交数据。
内容的提问来源于stack exchange,提问作者FranLegon
相关产品推荐
相关产品推荐

