SQL Server 2005
SQL Server 2008
SQL Server 2008 R2
有朋友來信詢問:
--EX1. WITH (NOLOCK) select * from mytest with (nolock) GO --EX2. unlock select * from mytest unlock GO
以上,這兩句語法有什麼差異?
(一)關於 EX1. WITH (NOLOCK)
NOLOCK:這相當於 READUNCOMMITTED。
READUNCOMMITTED
指定允許中途讀取。
不會發出任何共用鎖定來防止其他交易修改目前交易所讀取的資料,其他交易所設定的獨佔鎖定也不會封鎖目前交易,使它無法讀取鎖定的資料。
允許中途讀取可以提高並行程度,但代價是所讀取的資料修改後來會被其他交易回復。
這可能會使您的交易發生錯誤、為使用者提供永遠不被認可的資料,或是讓使用者看到記錄兩次 (或是根本看不到)。
如需有關中途讀取、不可重複讀取和幽靈讀取的詳細資訊,請參閱<並行效果>。
READUNCOMMITTED 和 NOLOCK 提示只適用於資料鎖定。
所有的查詢 (包括具有 READUNCOMMITTED 和 NOLOCK 提示的查詢),都會在編譯和執行期間取得 Sch-S (結構描述穩定性) 鎖定。
因此,當並行交易在資料表上保有 Sch-M (結構描述修改) 鎖定時,查詢將會遭到封鎖。
例如,資料定義語言 (DDL) 作業會在修改資料表的結構描述資訊之前先取得 Sch-M 鎖定。
任何並行查詢,包括以 READUNCOMMITTED 或 NOLOCK 提示執行的查詢,會在嘗試取得 Sch-S 鎖定時遭到封鎖。
相反地,保有 Sch-S 鎖定的查詢將會封鎖嘗試取得 Sch-M 鎖定的並行交易。
如需有關鎖定行為的詳細資訊,請參閱<鎖定相容性 (Database Engine)>。
無法針對插入、更新或刪除作業修改的資料表指定 READUNCOMMITTED 和 NOLOCK。
SQL Server 查詢最佳化工具會忽略套用在 UPDATE 或 DELETE 陳述式目標資料表的 FROM 子句中的 READUNCOMMITTED 和 NOLOCK 提示。
SQL Server 的未來版本將移除套用到 UPDATE 或 DELETE 陳述式目標資料表的 FROM 子句中 READUNCOMMITTED 和 NOLOCK 提示的使用支援。
請避免在新的開發工作中使用此內容中的這些提示,並規劃修改目前在使用這些提示的應用程式。
您可以使用下列其中一個選項,防止交易讀到尚未認可的資料修改 (中途讀取),同時也將鎖定爭用的情況減到最低:
(1) READ_COMMITTED_SNAPSHOT 資料庫選項設為 ON 的 READ COMMITTED 隔離等級。
(2) SNAPSHOT 隔離等級。
(二)關於 EX2. unlock
印象中,SQL Server 沒有 unlock 這類的用法,這應該是「資料表別名(Table Aliases)」的寫法,請參考以下的範例程式碼:
--01 查詢資料表:Orders -- 回傳 830 筆資料列。 USE Northwind GO SELECT * FROM Orders GO --02 設定「資料表別名(Table Aliases)」為:unlock -- 回傳 830 筆資料列。 SELECT * FROM Orders unlock GO --03 使用此「資料表別名」,搭配 WHERE 子句來篩選資料列 -- 僅是回傳 1 筆資料列。 SELECT * FROM Orders unlock WHERE unlock.OrderID =10248 GO
也就是說,若是使用 EX1. WITH (NOLOCK),是允許「中途讀取」。
若是使用 EX2. unlock,應該是當「資料表別名(Table Aliases)」來使用,無法支援「中途讀取」。
在此,感謝熊爺的解惑與說明。
參考資料:
資料表提示 (Transact-SQL)
http://msdn.microsoft.com/zh-tw/library/ms187373.aspx
使用資料表別名
http://msdn.microsoft.com/zh-tw/library/ms187455%28v=SQL.105%29.aspx
聯結基礎觀念
http://msdn.microsoft.com/zh-tw/library/ms191517%28v=SQL.105%29.aspx
沒有留言:
張貼留言