數據庫並發情況下什么情況會出現臟讀,如何防范臟讀


BEGIN tran
DECLARE @name NVARCHAR(50)
SELECT @name=name FROM dbo.investor WITH(UPDLOCK) WHERE id=1206
IF @name='sxf359'
BEGIN
UPDATE dbo.investor SET name='sxfabc' WHERE id=1206
END
PRINT @name
WAITFOR DELAY '0:00:20'
COMMIT TRAN
此事務在執行過程中,如果使用

SELECT * FROM dbo.investor WITH(NOLOCK)  WHERE id=1206

讀取該條數據,感覺上name字段應該讀取到的是sxf359。我一直是這樣認為的,因為事務還沒提交,還沒更新為sxfabc。但事實是讀取到的是sxfabc。把事務未最終提交的數據讀取出來了。一些“臟數據”或未被提交的數據潛在的可能被讀取,這就是臟讀。我對臟讀的定義有了更清晰的認識。

若用SELECT * FROM dbo.investor   WHERE id=1206 讀取數據,或者SELECT * FROM dbo.investor WITH(UPDLOCK) WHERE id=1206 讀取數據,這個時候都會處於等待狀態,直到事務執行完畢,才會執行這個兩個讀取操作

但,如果是下面的事務情況:


1
2
3
4
5
6
7
BEGIN tran
DECLARE @name NVARCHAR(50)
SELECT @name=name FROM dbo.investor WITH(UPDLOCK) WHERE id=1206
 
PRINT @name
WAITFOR DELAY '0:00:20'
COMMIT TRAN


下面的這兩條語句同時都能夠執行:

SELECT * FROM dbo.investor WITH(NOLOCK)  WHERE id=1206

SELECT * FROM dbo.investor   WHERE id=1206

 

但是,下面這條語句不能執行:

SELECT * FROM dbo.investor WITH(UPDLOCK) WHERE id=1206

這條語句只有在事務執行完畢才會執行。

updlock意思就是更新鎖

防范臟讀,保險的方法是使用 with(updlock)   ,但通常像這種正常讀取SELECT * FROM dbo.investor   WHERE id=1206 就可以了。因為若使用with(updlock)情形下,下步必然是要更新數據​
————————————————


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM