TL; DR
CREATE TABLE TESTE ( ID INT NOT NULL PRIMARY KEY, VALOR CHAR(1) )
INSERT INTO TESTE(ID,VALOR)
VALUES (1,'A'),(2,'B'),(3,'C')
Run this instruction in a SQL
BEGIN TRANSACTION Transaction1
DELETE FROM TESTE
WHERE ID=1
UPDATE TESTE
SET VALOR= 'D'
WHERE VALOR='C'
INSERT INTO TESTE(ID, VALOR)
VALUES(4,'E'),(5,'F') GO WAITFOR DELAY '00:00:05'
ROLLBACK
In another window also
SELECT * FROM TESTE WITH (NOLOCK)
The result will be :
Aftercompletingthefirsttransaction,rotatetheselectagain,seethattheresulthaschanged.
Didyounoticethedifference?
ByusingtheNOLOCK
hintnotonlycanyoureadmodifieddatabutalsoreadincorrectdata,whichisaresultofchangesinthephysicallocationofdatamadebyothertransactions.(Asshownintheaboveexample)
ChangingtoREADPAST
SELECT*FROMTESTE(READPAST)
Result:
ThisisbecausethisistheonlyrowthathasnotbeenmodifiedbyTransaction1
CONCLUSION
NOLOCK
allowsreadingofdirtylines(linesbeingusedbyothertransactions)andcancauseconsistencyproblemsduringTable/IndexScan
operations.NOLOCK
cangreatlyimproveperformance( Como usar SELECT WITH NOLOCK para melhorar a Performance?
), but be careful about this, see the Efeitos colaterais do WITH (NOLOCK) – Parte I
read lines that are not being used by other transactions.
I recommend reading: