Обновление: это до сих пор остается загадкой.Проверил код вызова, и мы не нашли ничего, что заставляло бы SP работать в цикле.На данный момент мы разделили SP на две части, что, похоже, остановило проблему, но не в состоянии объяснить, как это помогло.
База данных: MS SQL Server.
У меня есть SP, который выполняет несколько операций - т.е. вставляет строку в 3 таблицы на основе определенного статуса как часть вызываемого SP.
Он вызывается из нашего веб-приложения на основе действий пользователя.
У нас есть случаи, несколько раз в день, когда одна и та же строка вставляется несколько раз (иногда более 50+) с одинаковыми значениями в каждой строке, за исключением того, что если вы посмотрите на дату и время, когда строка была вставлена тударазница в несколько миллисекунд.Поэтому маловероятно, что пользователь инициирует это действие.
Этот SP не запущен в транзакции или с какой-либо блокировкой, однако он вызывается, вероятно, одновременно несколько раз, поскольку у нас есть много одновременных пользователей в веб-приложении, вызывающем это действие.
Мой вопрос: что заставляет вставлять одну и ту же строку столько раз?Если одновременное выполнение SP было проблемой, когда мы обновляем одну и ту же строку, то считается, что одно может перезаписать другое.Однако в этом случае каждый пользователь вызывает в SP с разными параметрами.
Я поместил указанную операцию в транзакцию для отслеживания поведения, однако пытался выяснить, что именно вызывает такого рода множественные вставки с одинаковым значением на расстоянии нескольких миллисекунд?
USE [ABC]
GO
/****** Object: StoredProcedure [dbo].[AddProcessAdmittedDocUploadScrutinyWithLog] ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[AddProcessAdmittedDocUploadScrutinyWithLog]
(
--Insert using bulk
@stdfrm_id int,
@course_id int,
@stdfrm_scrt_apprvby int,
@stdfrm_scrt_apprvcomment varchar(max),
@sRemainingDocs varchar(max),
@DTProcessAdmittedDocUploadScrutiny AS dbo.MyDTProcessAdmittedDocUploadScrutiny READONLY
)
AS
BEGIN
DECLARE @result char
SET @result='N'
--New
declare @AuditCount int=0;
select @AuditCount=count(scrtaudit_id) from tbl_ProcessAdmittedScrutinyAuditLog
where stdfrm_id=@stdfrm_id and stdfrm_scrt_apprvby=@stdfrm_scrt_apprvby
and stdfrm_scrt_apprvcomment=@stdfrm_scrt_apprvcomment and convert(date,stdfrm_scrt_apprvon,103)=convert(date,getdate(),103)
--Checked extra conditon to avoid repeatation
if(@AuditCount=0)
BEGIN
--Call Insert
BEGIN TRY
/*Remaining Documents----------*/
DECLARE @sdtdoc_id Table (n int primary key identity(1,1), id int)
if(@sRemainingDocs is not null)
begin
--INSERT INTO @sdtdoc_id (id) SELECT Name from splitstring(@sRemainingDocs)
INSERT INTO @sdtdoc_id (id) SELECT [Value] from dbo.FN_ListToTable(@sRemainingDocs,',')
end
Declare @isRemaining int=0;
SELECT @isRemaining=Count(*) FROM @sdtdoc_id
/*Calculate stdfrm_scrt_apprvstatus*/
Declare @stdfrm_scrt_apprvstatus char(1)='A';--Approved
Declare @TotalDescripancies int;
select @TotalDescripancies=count(doc_id) from @DTProcessAdmittedDocUploadScrutiny where doc_id_scrtyn='Y'
if(@isRemaining>0)
begin
set @stdfrm_scrt_apprvstatus='H';--Discrepancies Found
end
else if exists (select count(doc_id) from @DTProcessAdmittedDocUploadScrutiny where doc_id_scrtyn='Y')
begin
if(@TotalDescripancies>0)
begin
set @stdfrm_scrt_apprvstatus='H';--Discrepancies Found
end
end
/* Check if Discrepancies Found first time then assign to Checker o.w assign to direct college like grievance*/
if(@stdfrm_scrt_apprvstatus='H')
begin
declare @countAuditLog int=0;
select @countAuditLog=count(stdfrm_id) from tbl_ProcessAdmittedScrutinyAuditLog where stdfrm_id =@stdfrm_id
if (@countAuditLog=0)
begin
set @stdfrm_scrt_apprvstatus='G'--'E';--Discrepancies Found set Edit request assign to Checker
end
--else if (@countAuditLog=1)
-- begin
--set @stdfrm_scrt_apprvstatus='G';--Discrepancies Found set Grievance assign to college
-- end
end
/*----------------------*/
/*Update status in original table-----*/
Update tbl_ProcessAdmitted set stdfrm_scrt_apprvstatus=@stdfrm_scrt_apprvstatus
,stdfrm_scrt_apprvon=getdate(),stdfrm_scrt_apprvby=@stdfrm_scrt_apprvby
,stdfrm_scrt_apprvcomment=@stdfrm_scrt_apprvcomment
where stdfrm_id =@stdfrm_id
/*Add in Main Student Log-----------*/
/********* The row here gets inserted multiple times *******************/
INSERT into tbl_ProcessAdmittedScrutinyAuditLog
(stdfrm_id, stdfrm_scrt_apprvstatus, stdfrm_scrt_apprvon, stdfrm_scrt_apprvby, stdfrm_scrt_apprvcomment )
values
(@stdfrm_id, @stdfrm_scrt_apprvstatus, getdate(), @stdfrm_scrt_apprvby, @stdfrm_scrt_apprvcomment)
DECLARE @scrtaudit_id int =@@identity
/*Completed -------------------------*/
DELETE FROM tbl_ProcessAdmittedDocUploadScrutiny WHERE stdfrm_id =@stdfrm_id
SET NOCOUNT ON;
/********* The row here gets inserted multiple times *******************/
INSERT tbl_ProcessAdmittedDocUploadScrutiny
(stdfrm_id, course_id, doc_id, doc_id_scrtyn, doc_id_scrtrmrk, doc_id_comment)
SELECT @stdfrm_id, @course_id, doc_id, doc_id_scrtyn, doc_id_scrtrmrk, doc_id_comment
FROM @DTProcessAdmittedDocUploadScrutiny;
/*Scrutiny Document Log -------------------------*/
/********* The row here gets inserted multiple times *******************/
INSERT tbl_ProcessAdmittedDocUploadScrutinyAuditLog
(scrtaudit_id,stdfrm_id, course_id, doc_id, doc_id_scrtyn, doc_id_scrtrmrk, doc_id_comment)
SELECT @scrtaudit_id,@stdfrm_id, @course_id, doc_id, doc_id_scrtyn, doc_id_scrtrmrk, doc_id_comment
FROM @DTProcessAdmittedDocUploadScrutiny;
/*Remaining Documents Insert into table*/
DELETE FROM tbl_ProcessAdmittedDocUploadScrutinyRemiaing WHERE stdfrm_id =@stdfrm_id
DECLARE @Id int,@doc_id int
WHILE (SELECT Count(*) FROM @sdtdoc_id) > 0
BEGIN
Select Top 1 @Id = n,@doc_id=id From @sdtdoc_id
--Do some processing here
insert into tbl_ProcessAdmittedDocUploadScrutinyRemiaing(stdfrm_id, doc_id )
values (@stdfrm_id,@doc_id)
insert into tbl_ProcessAdmittedDocUploadScrutinyRemiaingAuditLog
(scrtaudit_id, stdfrm_id, doc_id )
values (@scrtaudit_id,@stdfrm_id,@doc_id)
DELETE FROM @sdtdoc_id WHERE n = @Id
END --Begin end While
/*End Remaining Documents-----------*/
SET @result=@stdfrm_scrt_apprvstatus
END TRY
BEGIN CATCH
SET @result='N'
insert into tbl_ErrorSql( ErrorMessage, stdfrm_id)
values(coalesce(Error_Message(),ERROR_LINE()),@stdfrm_id)
END CATCH;
--End of Call Insert
END
SELECT @result
END