我有一個複雜的選擇查詢和一個巨大的表。SQL Server - 確實[SELECT]鎖定[UPDATE]?
我跑這個select
聲明,同時一個Update
聲明到來,並試圖更新表。
恕我直言 - 更新需要獨家鎖 - 這樣的更新語句將不得不等待直到選擇命令完成。
對不起,對嗎?
我該怎麼才能做到:執行復雜
select
,和也讓update
命令運行(目前我不在乎髒數據)
我有一個複雜的選擇查詢和一個巨大的表。SQL Server - 確實[SELECT]鎖定[UPDATE]?
我跑這個select
聲明,同時一個Update
聲明到來,並試圖更新表。
恕我直言 - 更新需要獨家鎖 - 這樣的更新語句將不得不等待直到選擇命令完成。
對不起,對嗎?
我該怎麼才能做到:執行復雜select
,和也讓update
命令運行(目前我不在乎髒數據)
是 - 學位。
一個SELECT
取決於事務的隔離級別持有的共享鎖多久:
READ UNCOMMITTED
- 沒有共享鎖被收購的話 - UPDATE
不堵塞READ COMMITTED
- 共享僅在讀取數據期間獲取鎖 - UPDATE
可能會在很短的時間內被阻止REPEATABLE READ
和SERIALIZABLE
- 共享鎖被獲取並保留在unti升的事務的結束 - UPDATE
被阻塞,直到SELECT
事務結束技術上,UPDATE
語句首先得到一個UPDATE
鎖 - 其爲具有共享鎖(如所使用的SELECT
)兼容 - 爲對持續時間當它正在讀取要更新的行的當前值時。
一旦完成,Update
鎖升級爲獨佔鎖,以便將新數據寫入表中。
'UPDATE語句首先得到一個UPDATE鎖 - 它與共享鎖兼容'我不明白MARC。更新正在等待選擇完成? – 2012-08-06 14:35:15
@RoyiNamir:更新可以獲取'Update'鎖(讀取「舊」數據),而另一個進程仍在讀取同一行並在該行上具有「共享」鎖。但是,只要該共享鎖仍然存在,更新將無法進入獨佔鎖(將「新」數據寫回),因此它必須在那裏等待...... – 2012-08-06 14:35:56
當您同時運行這兩個語句(SELECT和UPDATE)時,實際行爲將基本上是隨機的。這是因爲這兩種操作都不是即時的。爲了簡化,請將您的表視爲列表,並且SELECT正在遍歷此列表,一次查看一行。 UPDATE也試圖更新一個或多個行。當UPDATE嘗試更新後面的行時,SELECT將不會發生任何事情(無阻塞),因爲SELECT已經超越了UPDATE點。如果UPDATE試圖更新SELECT正在查找的行現在那麼UPDATE將不得不等待SELECT繼續前進,這將發生得非常非常快,並且UPDATE將取消阻止併成功,而 SELECT正在向前邁進。但是,如果更新正在更新前面的SELECT,那麼更新將成功,並且,後面的,SELECT最終將到達此行並停止,阻止。現在SELECT必須等待,直到執行UPDATE的事務提交。
這是簡單的故事。現實生活要複雜得多。 SELECT可以有多個讀取點(並行計劃)。 SELECT和UPDATE都可以選擇訪問路徑,也就是說使用一個或多個二級索引來定位行。複雜查詢可能包含導致對錶進行多重查詢的運算符(例如連接)。 SELECT和UPDATE都可以執行書籤查找來獲取BLOB數據,這顯着改變了鎖定行爲。基數估計可能會導致SELECT以高粒度鎖定模式運行(例如,表級別共享鎖定)。 UPDATE可以觸發鎖升級,升級可能失敗或成功。 Choosing different access paths can lead to deadlock。 False lock contention can occur due to hash collisions。只有大約一個變量在這方面有發言權。而且我甚至沒有提到更高的隔離級別(可重複讀取,可序列化)。
也許你應該使用SNAPSHOT隔離並停止擔心這個問題?
如果你建議使用'SNAPSHOT'進行操作 - 只要確保'TempDB'設置正確! (數據文件的位置和數量,大小選項等) – 2012-08-06 14:08:30
是,可重複和可序列化會導致事務處理範圍中保留共享鎖。可序列化還可以添加範圍鎖定。所有這些增加了複雜性 – 2012-08-06 14:08:32
@marc_s:到MSDN主題的鏈接包含[行版本資源使用](http://msdn.microsoft.com/zh-cn/library/ms175492(v = sql.105))。我寧願不要嚇跑用戶,因爲我認爲SNAPSHOT的好處遠遠超過其成本。 – 2012-08-06 14:10:53
你在說什麼事務隔離級別? – Oded 2012-08-06 13:47:14
@Oded默認 - 我相信它是讀取提交。 – 2012-08-06 13:48:21
*「目前我不在乎髒數據」*:小心[你想要什麼](http://blogs.msdn.com/b/sqlcat/archive/2007/02/01/previously-committed-行,可能-錯過的-IF-NOLOCK-提示的是,used.aspx)。 – 2012-08-06 14:13:47