2013-02-25 189 views
1

我有一個名爲Products的表,它有很多列。避免併發刪除造成死鎖

這是一個用於報告目的的臨時表。這些數據將被多個用戶請求的同時進行處理,以該表(單獨的存儲過程進行DML操作此表)

表結構: 創建表產品 (例如唯一標識符, 插入日期時間, COL1,COL2 ,...)

插入的列將填充GETDATE()以在插入數據時生成。而實例列有newid()值。一個用戶請求將有一個唯一的ID;可能有百萬行。以下是將會同時執行的查詢,這會導致死鎖。請告訴我

查詢1: 「設置事務隔離READUNCOMMITTED 刪除產品(NOLOCK)P其中例如= 'XXXX-XXX-XXX-XX'」

QUERY2: 「設置事務隔離READUNCOMMITTED 刪除P從產品(NOLOCK)其中插入< = DATEADD(HH,-10,GETDATE())」

注:非聚簇索引是在實例列創建。

請告訴我我可以在這種情況下使用哪個鎖。

注意我無法使用主鍵,因爲當我向表中插入1000萬行時(這是一個事務;有20個併發轉換),因此它很耗時間。 報告應該儘快生成。我的過程有多個35個DML語句,大約有15個DELETE語句用於其他列的實例列(從表中DElete where instance = @instance和col1 = @ col1)。

+0

看看這個http://stackoverflow.com/questions/9952137/multi-threading-c-sharp-application-with-sql-server-database-calls/10035988#10035988 – Phil 2013-02-25 18:41:30

回答

5

(1)您應該停止使用read uncommitted隔離。至少使用read committed

(2)有一些事情你可以嘗試避免死鎖,就像確保以相同的順序您不同的事務訪問數據庫對象等,這將是值得一讀 - http://support.microsoft.com/kb/169960

(3)禁用你的表鎖升級(更細緻的鎖,以便更好的併發,多鎖開銷):

alter table Products set lock_escalation disable 

(4)不準予頁鎖,讓您的索引行鎖(意味着你不能碎片整理的索引,但你仍然可以重建它們):

alter index [<YourIndex>] on Product set (allow_row_locks = on, allow_page_locks = off) 
1

首先,除了獨佔鎖之外,您可以對這些刪除語句執行鎖定。您的isolation level and NOLOCK hints are being ignored by Sql Server

(Nolock)僅適用於SELECT聲明。

兩個建議:

instance的非聚集索引更改爲聚集索引。但只有這樣做,如果你可以改變NEWID()NEWSEQUENTIALID()

二,而不是執行delete刪除超過10小時的記錄...考慮implementing rolling partitions。這將消除由您的其他delete操作導致的清理引起的任何爭用。