高併發讀寫場景下,SELECT 被寫入交易阻塞,甚至觸發死鎖(Error 1205),導致查詢中斷。
SELECT au_lname
FROM authors WITH (NOLOCK);
等價於設定交易隔離等級 READ UNCOMMITTED,讀取時不申請共享鎖,直接讀取資料頁當前版本(含未提交資料)。
| 優點 | 缺點/風險 |
|---|---|
| 完全不阻塞寫入,查詢極快 | 可能讀到「髒資料」(未提交/已回滾的資料) |
| 不持有鎖,減少死鎖機率 | 可能出現「幻讀」或「不可重複讀」 |
| 語法簡單,無需改應用邏輯 | 索引掃描時可能遇到頁分裂導致錯誤 601 |
ALTER DATABASE db SET READ_COMMITTED_SNAPSHOT ON,讀寫不再互相阻塞,語意上保證語句級一致性。SET TRANSACTION ISOLATION LEVEL SNAPSHOT,需應用程式顯式開啟交易,適合長交易一致性讀。預設開啟 RCSI,僅在極少數「寧可髒讀不可阻塞」的報表查詢上加
WITH (NOLOCK),並在程式碼註解標註風險承擔者。