【发布时间】:2018-02-09 17:06:54
【问题描述】:
当前运行以下 SQL 语句的位置(可能同时运行 30 或 40 次)并给我们带来死锁错误,但我们不确定哪些语句相互干扰。除了 PK 和 Fk 到 ThingTypes 表之外,Things 表上没有索引。我们还想知道向 ThingTypeId 和 HourId 添加索引是否有助于解决问题。最后,我们还可以安全地假设 {@thingTypeID 和 @hourID} 对于所有并发查询都是唯一的,并且 if 仅在稍后重新运行时才存在。
事务(进程 ID 237)在锁定资源上与另一个进程死锁,并已被选为死锁牺牲品。重新运行事务
代码:
IF NOT EXISTS(select top(1) id from [eddsdbo].[Things] (UPDLOCK)
where [ThingTypeID] = @thingTypeID and [HourID] = @hourID)
BEGIN
INSERT INTO [eddsdbo].[Things]
([ThingTypeID]
,[HourID])
VALUES
(@thingTypeID
,@hourID)
SELECT m.*, mt.SampleType
FROM [eddsdbo].[Things] as m
inner join [eddsdbo].[ThingTypes] as mt on mt.Id = m.ThingTypeID
WHERE m.ID = @@IDENTITY
END
ELSE
BEGIN
SELECT m.*, mt.SampleType
FROM [eddsdbo].[Things] as m
inner join [eddsdbo].[ThingTypes] as mt on mt.Id = m.ThingTypeID
where [ThingTypeID] = @thingTypeID and [HourID] = @hourID
END
我们一直在追查这个问题一段时间,因此感谢您提供任何帮助。
【问题讨论】:
-
旁白:
Scope_Identity()几乎总是比@@Identity更好的选择。您还可以使用OUTPUT子句从行中获取任何数据(注意复数。),例如新插入行的标识列值。OUTPUT可以与INSERT、UPDATE、DELETE和MERGE一起使用,并且在 @ 的情况下提供对 before 和 after 值的访问987654332@。一个非常值得放在口袋里的工具。
标签: sql-server tsql transactions deadlock