我有一個應用程序連接到一個SQL Server 2014數據庫,它將幾行組合成一個。應用程序運行時沒有其他數據庫連接。防止SQL Server中的死鎖
首先,在特定時間範圍內選擇一大塊行。此查詢使用與聚簇查找合併的非聚簇查找(TIME列)。
select ...
from FOO
where TIME >= @from and TIME < @to and ...
然後,我們在c#中處理這些行,並將更改寫入單個更新和多個刪除,每個塊會發生多次。這些也使用非聚集索引查找。
begin tran
update FOO set ...
where NON_CLUSTERED_ID = @id
delete FOO where NON_CLUSTERED_ID in (@id1, @id2, @id3, ...)
commit
我在使用多個並行塊運行時出現死鎖。我嘗試使用ROWLOCK
作爲update
和delete
,但由於某些原因,導致甚至比以前更多的死鎖,即使塊之間沒有重疊。
然後我試着TABLOCKX, HOLDLOCK
在update
,但這意味着我不能執行我的select
並行,所以我失去了並行的優勢。
任何想法如何我可以避免死鎖,但仍然處理多個平行塊?
在這種情況下,在我的select
上使用NOLOCK
是否安全?因爲塊之間沒有行重疊?那麼TABLOCKX, HOLDLOCK
只會阻止update
和delete
,對嗎?
或者我應該接受死鎖會發生並重試我的應用程序中的查詢?
UPDATE(附加信息):所有死鎖迄今已在update
和delete
階段發生的事情,沒有在select
。如果今天我無法解決這個問題,我會嘗試獲取一些死鎖日誌(之前未啓用正確的跟蹤標誌)。
UPDATE:這些是與ROWLOCK
發生死鎖的兩個安排,他們都僅指delete
聲明和它使用的非聚集索引。我不確定這些是否與沒有任何表格提示的死鎖一樣,因爲我無法再現這些問題。
問,如果有什麼事,從.xdl別的需要,我有點厭倦連接整個事情的。
你在選擇過程中是否嘗試過聲稱'UPDLOCK'?這樣,當你更新/刪除應該讓你遠離死鎖時,鎖已經在那裏了。如果可能的話,與我們分享一些死鎖記錄的細節。 – Jens
您可以將所有處理移動到存儲過程嗎?你也可以通過簡單地打開快照隔離來解決這個問題,但這取決於你在做什麼。 –
@Jens很抱歉,我現在無法獲取死鎖日誌。看起來,由於死鎖而失敗的所有線程都處於'update'和'delete'階段,因此更改'select'鎖定不太可能影響這種情況。不幸的是,我沒有任何死鎖日誌,我會看看是否可以獲取爲下一次嘗試啓用的死鎖跟蹤標誌。 @ Nick.McDermaid不幸的是不能使用快照隔離。 –