2010-03-22 62 views
4

我有一個SQL Server中的死鎖問題,我無法解決。SQL死鎖刪除然後批量插入

基本上,我有大量的併發連接(從許多機器)執行事務,他們首先刪除一系列條目,然後用批量插入重新插入相同範圍內的條目。

本質上來說,交易看起來像這樣

BEGIN TRANSACTION T1 
DELETE FROM [TableName] WITH(XLOCK HOLDLOCK) WHERE [Id][email protected] AND [SubId][email protected] 

INSERT BULK [TableName] (
[Id] Int 
, [SubId] Int 
, [Text] VarChar(max) COLLATE SQL_Latin1_General_CP1_CI_AS 
) WITH(CHECK_CONSTRAINTS, FIRE_TRIGGERS) 

COMMIT TRANSACTION T1 

批量插入只是插入項目配套缺失的ID和子ID在同一事務。此外,這些Id和SubId條目不應該重疊。

當我有足夠的這種形式的併發事務時,我開始在這些語句之間看到大量的死鎖。

我添加了鎖定提示XLOCK HOLDLOCK來嘗試處理這個問題,但他們似乎並沒有幫助。

的規範死鎖圖形此錯誤顯示:

連接1:

  • 持有PK_TableName RangeX-X
  • 在桌子上
  • 請求X頁鎖定存放IX頁鎖表

連接2:

  • 上表所擁有的九頁鎖在表上

我需要什麼,以確保不發生這些死鎖做

  • 要求RangeX-X鎖。

    我一直在對RangeX-X鎖進行一些閱讀,我不確定我是否完全理解這些情況。我有沒有任何選項可以鎖定整個表格?

  • 回答

    1

    如果沒有索引/表大小等列表,它很難給你一個準確的答案,但請記住,SQL不能在同一個實例中獲取多個鎖。它會一次抓取一個鎖,並且如果另一個連接已經擁有該鎖並且它對第一個事務需要的某個鎖具有鎖定,那麼kaboom會導致死鎖。

    在這種特定情況下有幾件事情可以做:

    1. 確保有上(ID,子ID)的索引,這樣,SQL將能夠搶單範圍鎖的數據被刪除。
    2. 如果死鎖很罕見,請重試您的死鎖。
    3. 您可以用sledghammer接近這一點,並使用它不會死鎖永遠
    4. 一個TABLOCKX使用跟蹤標誌得到一個準確的僵局分析1204 http://support.microsoft.com/kb/832524(您對實際死鎖的更多信息就越容易解決)
    2

    從薩姆藏紅花的回答繼:

    • 考慮READPAST提示跳過任何持有的鎖如果@ ID7 @子ID是distinc
    • 考慮SERIALI ZABLE並移除XLOCK,HOLDLOCK
    • 對批量插入使用單獨的臨時表,然後從該臨時表複製