READ UNCOMMITTED 允许您读取尚未被其他事务提交的脏数据。 SQL Server 引擎忽略正在读取的表下的任何锁,直接从内存中读取数据。
READ COMMITTED 将读取已经提交的数据,但如果数据受到其他事务的影响,则会等待。
因此,在示例中,系统不仅在读取,而且还在尝试删除尚未提交的行,因此,两者都将等待另一个事务完成,因此,该示例是 DEADLOCK 的典型示例。
为了说明 COMMITTED 与 UNCOMMITTED 之间的区别,我将向您展示一个简单明了的示例,我们将在两种模式下运行两次。
-- Query Window 1
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; -- Prepare for first Run
SET TRANSACTION ISOLATION LEVEL READ COMMITTED; -- Prepare for second Run
BEGIN TRANSACTION -- Step 1
INSERT INTO Audit (ProductID, PrevValue, NewValue, ChangedBy)
VALUES (1, 'AAA', 'aaa', SYSTEM_USER); -- Step 3
COMMIT TRANSACTION -- Step 5
-- Query Window 2
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; -- Prepare for first Run
SET TRANSACTION ISOLATION LEVEL READ COMMITTED; -- Prepare for second Run
BEGIN TRANSACTION -- Step 2
SELECT * FROM Audit WHERE PrevValue = 'AAA' -- Step 4
COMMIT TRANSACTION -- Step 6
我们必须首先在两个查询中运行 UNCOMMITTED LEVEL 行,然后转到第一个,运行第 1 步,转到第二个,第 2 步,依此类推。
在我们运行第 4 步时的 UNCOMMITTED 中,我们将立即看到结果,因为我们正在进行脏读(从内存中)。
对于第二次运行,我们将首先删除行测试:
DELETE FROM Audit WHERE PrevValue LIKE 'AAA';
然后,将在两个查询窗口中运行 COMMITTED LEVEL 行并运行相同的序列。
现在我们将观察到,当我们运行第 4 步时,系统仍然没有响应。就在我们运行第 5 步提交插入的那一刻,窗口将显示结果。
我希望现在的问题更清楚了。