虽然我的数据库隔离级别设置为 READ_COMMITTED_SNAPSHOT,但我仍然会发生脏(未提交)读取。
SELECT COUNT([random_string]) NoTx FROM [dbo].[IncTesting5];
BEGIN TRANSACTION;
INSERT INTO [IncTesting5] ([random_string]) VALUES ('UncommittedRow1'),('UncommittedRow2');
SELECT COUNT([random_string]) NoHint FROM [dbo].[IncTesting5];
SELECT COUNT([random_string]) WIthHint FROM [dbo].[IncTesting5] WITH (READUNCOMMITTED);
ROLLBACK TRANSACTION;
该查询返回 NoTx = 0、NoHint = 2、WIthHint =2。我希望 NoHint 等于 0。
带有
SELECT COUNT([random_string]) NoHint
的查询是发生 INSERT
的同一事务的一部分。 SQL Server 允许事务查看自己未提交的更改,即使在 READ COMMITTED
下也是如此。这称为语句级读取一致性,但在您的事务范围内,您的事务的更改是可见的。
因此,查询会看到未提交的
INSERT
行,因为它们是同一事务的一部分。
如果在事务未提交时在单独的会话中执行
NoHint
查询,则由于 READ_COMMITTED_SNAPSHOT
设置,它将看不到未提交的行:
在上图中,会话 A 看到未提交的行,因为它们是同一事务的一部分,而位于
READ_COMMITTED_SNAPSHOT
下的会话 B 仅看到已提交的行(忽略会话 A 的未提交更改)。