当前运行以下SQL语句(可能同时运行30或40次)并且给我们发生死锁错误但我们不确定哪些语句相互干扰。除了PK和Fk到ThingTypes表之外,Things表上没有索引。我们还想知道是否向ThingTypeId和HourId添加索引将有助于解决问题。最后,我们也可以安全地假设{@ somethingTypeID和@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
我们一直在追讨这个问题,所以感谢任何帮助。
答案 0 :(得分:1)
不确定这会解决它
但是你真的需要WHERE m.ID = @@IDENTITY
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)
END
SELECT m.*, mt.SampleType
FROM [eddsdbo].[Things] as m
inner join [eddsdbo].[ThingTypes] as mt
on mt.Id = m.ThingTypeID
and [ThingTypeID] = @thingTypeID
and [HourID] = @hourID
单一陈述是交易
我认为这会减少开销
DECLARE @t AS TABLE (id int identity primary key, thingTypeID int, hourID int);
declare @thingTypeID int = 1, @hourID int = 2;
insert into @t (thingTypeID, hourID)
values (@thingTypeID, @hourID);
select *
from @T
where thingTypeID = @thingTypeID and hourID = @hourID;
insert into @t (thingTypeID, hourID)
select @thingTypeID, @hourID
where not exists (select 1 from @t where thingTypeID = @thingTypeID and hourID = @hourID);
select *
from @T
where thingTypeID = @thingTypeID and hourID = @hourID;
set @thingTypeID = 1;
set @hourID = 3;
insert into @t (thingTypeID, hourID)
select @thingTypeID, @hourID
where not exists (select 1 from @t where thingTypeID = @thingTypeID and hourID = @hourID);
select *
from @T
where thingTypeID = @thingTypeID and hourID = @hourID;
select *
from @T
order by id;