1

我們在持有訂單履行的事務表中使用集羣列存儲索引。該表由不同的會話定期更新。但是,每個會話都是專門爲了訂購作業號而設計的,所以他們並不試圖同時更新同一行。但是,由於會議之間的情況不同,我們正面臨死鎖問題。發生在集羣列存儲索引中的死鎖

  • 行組鎖定&頁鎖
  • 行組鎖定&行組鎖定

這不是特定於存儲的過程。這是由於多個存儲過程逐一更新此表,作爲訂單履行的一部分。

表的示例模式很簡單:

CREATE TABLE OrderFulfillments 
(
    OrderJobNumber   INT NOT NULL, 
    FulfilledIndividualID BIGINT NOT NULL, 
    IsIndividualSuppressed BIT NOT NULL, 
    SuppressionReason  VARCHAR(100) NULL 
) 

我已經給定的樣本僵局圖,供大家參考。請讓我知道,我可以採取什麼方法來避免這種僵局。我們需要在此表中使用聚集的Columnstore索引,因爲我們正在執行聚合操作以查看個人已經實現了多少次。沒有列存儲索引,它可能會變慢。

enter image description here

+0

你需要問自己什麼查詢導致了阻塞。如果更新是真正的順序,那麼答案不是更新,而是其他過程,比如說表上的select語句。從sys.DM_exec_requests中找出last_wait_type是什麼 –

+0

是的,select語句仍然使用某種級別的鎖定。 –

+0

謝謝克利夫頓。我已在每個選擇查詢上應用NOLOCK。只有UPDATE,我們沒有NOLOCK來避免數據損壞。所以,選擇是不是這裏的問題。鎖定升級到Rowgroup級別導致死鎖。我會用等待類型信息 –

回答

0

在我的情況下,死鎖情況是由於鎖升級發生,因爲一些應驗都非常大,在10,000s或100K的範圍,它是導致鎖升級發生在rowgroup水平和一些情況下,頁面級別。

我解決了這個問題,在事務開始時有一個臨時表,並且處理臨時表上的更新,最後在臨時表中插入臨時表相關的履行信息到這個OrderFulfillments。這個OrderFulfillments也被臨時表用來查看個人已經完成了多少次。但是,它是頂部的共享鎖而不是獨佔鎖。

通過使用臨時表,每個會話都在自己的副本上工作,併發問題得到解決。

1

你呈現NOLOCK是一樣的,因爲沒有鎖定...這是不正確。

NOLOCK相當於READUNCOMMITTED。

•READUNCOMMITTED和NOLOCK提示僅適用於數據鎖定。

編譯期間的所有查詢,包括那些READUNCOMMITTED和NOLOCK提示, 獲取SCH-S(架構穩定性)鎖和 執行。因此,當一個併發的事務在表上保留一個Sch-M(模式修改)鎖定時,查詢將被阻止。

例如,數據定義語言(DDL)操作在修改表的模式信息之前獲取Sch-M 鎖。

任何併發查詢,包括那些使用READUNCOMMITTED或NOLOCK提示運行的查詢,在嘗試獲取Sch-S鎖時都會被阻止。 相反,持有Sch-S鎖的查詢將阻止嘗試獲取Sch-M鎖的併發 事務。

對於經過 修改的表,不能指定READUNCOMMITTED和NOLOCK插入,更新或刪除操作。 SQL Server查詢優化器 將忽略FROM子句中的READUNCOMMITTED和NOLOCK提示, 應用於UPDATE或DELETE語句的目標表。

•與設置爲ON時 READ_COMMITTED_SNAPSHOT數據庫選項讀取已提交的隔離級別:

可以減少鎖定爭,同時保護交易從 髒通過使用該 的下列讀取未提交的數據修改。

•SNAPSHOT 隔離級別。有關隔離級別的更多信息,請參閱SET TRANSACTION ISOLATION LEVEL(Transact-SQL)。

https://docs.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-table

  • 瞭解您的索引是如何組織可引起如果說,一個select語句需要您的更新修改的同時整個頁面阻塞。

  • 限制測試後的變量。

  • 考慮將DML拆分爲多個部分。您可能會發現執行表數據併發修改的最佳範圍。

+0

更新你,並且停止非常多地使用NOLOCK。優化器通常足夠聰明,如果你使用NOLOCK的話,考慮一個不同的ISOLATION策略。 –