代码,注意值的顺序是不同的。因此,它交替锁定行之间:这个简单的代码会产生死锁。包含简单示例程序
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