READ UNCOMMITTED allows you to read the dirty data that has not been committed by other transactions. SQL Server engine ignores any lock under the table being read and reads the data directly from memory.
READ COMMITTED will read the data that has already been COMMITTED but will wait if the data is being affected by other transaction.
So, in the example provided the system is not only reading but also trying to DELETE a row that has still not been COMMITTED, so, both will wait until the other transaction finishes so, the example is a typical example for DEADLOCK.
To ilustrate the differences between COMMITTED vs UNCOMMITTED I will show you a simple and clear example that we will run twice, in the two modes.
-- 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
We have to run first the line for UNCOMMITTED LEVEL in both queries and then, go to first one, run Step 1, go to the second, step 2 and so on.
In the UNCOMMITTED when we run Step 4 we will see the results inmediately as we are doing a dirty read (from memory).
For second run, we will remove first the line test with:
DELETE FROM Audit WHERE PrevValue LIKE 'AAA';
Then, will run the line for COMMITTED LEVEL in both query windows and will run the same sequence.
We will observe that now, when we run Step 4 the system remains with no response. Just in the moment that we run Step 5 to commit the insert the window will show the results.
I hope that the question now is clearer.