[英]SQL Server 2008: how does NOLOCK works for CTE?
我有全部使用NOLOCK的CTE。 但是,然后從使用子級的父級CTE中的那些CTE中進行選擇,就不會假定NOLOCK已被使用,因此不使用NOLOCK。 最終選擇也不使用NOLOCK。
像這樣:
with cte1 as
(select * from tab1 (nolock)),
cte2 as
(select * from cte1)
select * from cte2
還是我寫
with cte1 as
(select * from tab1 (nolock)),
cte2 as
(select * from cte1 (nolock))
select * from cte2 (nolock)
謝謝
您不需要外部nolock
即可避免對tab1
進行共享鎖定。 您可以通過設置一個SQL事件探查器跟蹤來輕松地驗證這一點,該跟蹤器捕獲locks
類別中的各種事件,過濾SSMS連接的spid並嘗試這兩個版本。
nolock
是一個非常危險的設置,您是否知道使用它的所有可能的缺點(臟讀,兩次讀取數據或根本不讀取數據)?
“外部”查詢上的NOLOCK也適用於任何內部查詢。 CTE只是一個宏,如視圖或內聯表udf:僅此而已。 因此,您實際上擁有了(忽略NOLOCK提示)
select * from (
select * from (
select * from tab1
) t1
) t2
從MSDN上的表提示中的 “備注”下
所有鎖定提示都傳播到查詢計划訪問的所有表和視圖,包括視圖中引用的表和視圖。
在這種情況下,您只需要一個。 沒關系,在哪里。
重要的是您擁有JOIN的位置。 如果cte1是2個表的聯接,則每個表都需要它。 或在更高/更高級別指定一次。
哦,我將和其他所有人一起加入: NOLOCK是一個壞主意
最內層的nolock
就足夠了,無需為外部選擇重復它。
您可以通過啟動事務而不結束它來測試它:
begin transaction
; with YourCte ( ...
然后,您可以使用Management Studio查看鎖。 他們會一直在那兒直到交易超時。
CTE的NOLOCK的工作方式與其他一切相同:導致結果不一致 。 請改用SNAPSHOT,請參閱SQL Server 2005基於行版本控制的事務隔離 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.