我在并发用户的插件上遇到死锁。我开火的sp相对简单
SET NOCOUNT ON;
begin try
begin tran
DECLARE @idoc INT
declare @ProcessedResponse table (
candidateInstanceID int,
assessmetID int,
sectionID int,
itemID int,
clientID int,
displayTypeID int,
respondedAt datetime,
responseTime float,
marksObtained float,
processedresponseXML xml,
resultDescription varchar(255),
reportedIssue bit )
-- insert into @PartialResponse
EXEC sp_xml_preparedocument
@idoc OUTPUT,
@Processed_Responses
insert into @ProcessedResponse
SELECT *
FROM OPENXML(@idoc, '/Processed_Responses/Processed_Response', 1)
WITH (Candidate_Instance_ID int,
Assessment_ID int,
Section_ID int,
Item_ID int,
Client_ID int,
Display_Type_ID int,
Responded_At datetime,
Response_Time float,
Marks_Obtained float,
Processed_XML text,
Result_Description text,
Reported_Issue bit)
INSERT INTO Processed_Response
(Candidate_Instance_ID,
Assessment_ID,
Section_ID,
Client_ID,
Item_ID,
Display_Type_ID,
Responded_At,
Response_Time,
Marks_Obtained,
Processed_XML,
Result_Description,
Reported_Issue)
SELECT pr.candidateInstanceID,
pr.assessmetID,
pr.sectionID,
pr.clientID,
pr.itemID,
pr.displayTypeID,
cast(pr.respondedAt as datetime),
pr.responseTime,
case pr.marksObtained
when 0 then null
else pr.marksObtained
end,
CAST(pr.processedresponseXML AS XML),
pr.resultDescription,
pr.reportedIssue
FROM @ProcessedResponse pr
update pr
set pr.Client_ID = a.Assessment_Owner
from Processed_Response pr
join Assessment a
on pr.Assessment_ID = a.Assessment_Id
where pr.Candidate_Instance_ID = @Candidate_Instance_ID
update Candidate_Instance
set Instance_Status = 'Completed',
Instance_End_Time = GETDATE()
where Candidate_Instance_Id = @Candidate_Instance_ID
commit tran
end try
begin catch
DECLARE @ErrorMessage NVARCHAR(4000);
DECLARE @ErrorSeverity INT;
DECLARE @ErrorState INT;
SELECT @ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE();
rollback tran
-- Use RAISERROR inside the CATCH block to return error
-- information about the original error that caused
-- execution to jump to the CATCH block.
RAISERROR (@ErrorMessage,-- Message text.
@ErrorSeverity,-- Severity.
@ErrorState -- State.
);
end catch
任何人都可以帮助我谢谢。
答案 0 :(得分:0)
它需要两位代码才能死锁,所以同样的代码死锁本身也是如此?如果不知道表结构和索引用法,很难诊断出来。是你的update-select(update pr...
)表扫描并锁定整个表?等
BEGIN TRANS
移到INSERT INTO Processed_Response
之前,您不需要将所有局部变量填充到事务中。保持您的交易尽可能短。
设置SQL Server Profiler并得到一个死锁图跟踪,你会看到两个相互碰撞的SQL,并从那里开始。