代碼,注意值的順序是不同的。因此,它交替鎖定行之間:這個簡單的代碼會產生死鎖。包含簡單示例程序
static void Main(string[] args)
{
List<int> list = new List<int>();
for(int i = 0; i < 1000; i++)
list.Add(i);
Parallel.ForEach(list, i =>
{
using(NamePressDataContext db = new NamePressDataContext())
{
db.ExecuteCommand(@"update EBayDescriptionsCategories set CategoryId = Ids.CategoryId from EBayDescriptionsCategories
join (values (7276, 20870),(240, 20870)) as Ids(Id,CategoryId) on Ids.Id = EBayDescriptionsCategories.Id");
db.ExecuteCommand(@"update EBayDescriptionsCategories set CategoryId = Ids.CategoryId from EBayDescriptionsCategories
join (values (240, 20870),(7276, 20870)) as Ids(Id,CategoryId) on Ids.Id = EBayDescriptionsCategories.Id");
}
});
}
表DEF:
CREATE TABLE [dbo].[EDescriptionsCategories](
[CategoryId] [int] NOT NULL,
[Id] [int] NOT NULL,
CONSTRAINT [PK_EDescriptionsCategories] PRIMARY KEY CLUSTERED
(
[Id] ASC
)
例外:
Transaction (Process ID 80) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
的代碼只適用於WITH(TABLOCK)提示。是否有可能不鎖定整個表,只是爲了更新這兩行並行?
我試着設置(HOLDLOCK),它應該做同樣的事情。除WITH(TABLOCK)外沒有任何工作。我認爲正在發生的是開始單獨鎖定每一行。因爲它們從不同的行開始,所以會發生死鎖。我想知道在更新開始之前是否可以鎖定所有引用的行。 – Dennis
好吧,你以相反的順序更新這兩行,所以這些更新互相鎖定。你需要並行運行兩個在同一行上工作的查詢嗎? –
這是一個練習嗎?您不會故意嘗試在生產中的同一事務中並行更新兩行嗎? – Rikalous