国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

為什么NOLOCK查詢提示是個不明智的想法

2024-07-21 02:46:01
字體:
來源:轉載
供稿:網友
為什么NOLOCK查詢提示是個不明智的想法

一些人總當NOLOCK查詢提示是SQL Server里的加速器,因為它避免了大量的死鎖情景。在這篇文章里,我想向你展示下為什么NOLOCK查詢提示是個不好的想法。

臟讀(Dirty Reads)

NOLOCK查詢提示一個最大的副作用就是在你的記錄集會出現所謂的臟讀這個事實。我們來看下面的代碼:

1 BEGIN TRANSACTION2 3 UPDATE Person.Person4     SET FirstName = 'James'5 WHERE LastName = 'Jones'

如你所見,我開始了一個新的事務,對AdventureWorks2012數據庫里的Person.Person表進行UPDATE語句。現在當你嘗試同時在另一個會話里讀取這個記錄時,這個SELECT語句會阻塞——在這個情況下請求的共享鎖(S)會被已經授予的排它鎖(X)阻塞——寫阻塞讀操作。

1 SELECT2     FirstName,3     LastName4 FROM Person.Person5 WHERE LastName = 'Jones'6 GO

一些人現在回應用SQL Server里的加速器,使用NOLOCK查詢提示:

1 SELECT2     FirstName,3     LastName4 FROM Person.Person WITH (NOLOCK) -- It's a kind of magic...5 WHERE LastName = 'Jones'6 GO

如你所見死鎖情景馬上解決了,你從SQL Server返回記錄了——遺憾的是在你面前現在有臟讀(Dirty Read):你讀取了尚未提交的數據。假設現在用UPDATE語句的第1個事務回滾了:在這個情況下,你已讀取的數據在SQL Server里邏輯上是從未存在的。

因此NOLOCK查詢提示并不是在每個情景都是有用的。如果你想運行一個報表,或者你只想快速返回結果,記錄不用100%正確,這“可以是”個可取的(考慮下一天的平均銷售額)。當然,當你需要精確的結果,NOLOCK并不可取。當然也有一些特定場景即使NOLOCK也會阻塞。

讀提交快照隔離(Read Committed Snapshot Isolation (RCSI))

有人給我提了為什么NOLOCK查詢提示基本是一個不方便的(no-go)的選擇:你不能在明顯的方式里切換你的數據庫查詢到讀提交快照隔離(Read Committed Snapshot Isolation (RCSI))。我從未想過這個情景,但沒錯是對的。讀提交快照隔離(Read Committed Snapshot Isolation (RCSI))是個數據庫選項。當你啟用它的時候,每個查詢都是在新的讀提交快照樂觀隔離級別里——只要在你的事務里不指定任何隔離級別。

對于特定的SQL語句使用NOLOCK查詢提示,你臨時修改隔離級別為未提交讀(Read Uncommitted)。因此SQL語句也不會從讀提交快照隔離受益,因為語句并沒有在默認的提交讀(Read Committed)隔離運行。這就對了!當你下次寫下神奇的……WITH(NOLOCK)……時,好好想下這個額外參數。

小結

使用NOLOCK查詢提示運行每個查詢并不都有意義。一方面你會通過臟讀(Dirty Reads)返回不一致的數據。另一方面你不能從讀提交快照隔離(Read Committed Snapshot Isolation (RCSI))樂觀隔離級別里受益,因為你臨時修改了你SQL語句的默認隔離級別。

感謝關注!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 英吉沙县| 长岭县| 大荔县| 剑阁县| 惠安县| 加查县| 永德县| 垫江县| 闵行区| 南京市| 海兴县| 禹城市| 县级市| 容城县| 鹿邑县| 丹巴县| 旺苍县| 连州市| 修文县| 灵石县| 应用必备| 汕尾市| 洛宁县| 巴彦淖尔市| 盐津县| 广德县| 普兰店市| 稷山县| 沁阳市| 稷山县| 巴东县| 博乐市| 蒙山县| 霍州市| 佳木斯市| 周宁县| 台州市| 花垣县| 梅河口市| 和平县| 安平县|