更新:这仍然是一个谜。检查了调用代码,我们没有发现任何会使SP循环运行的内容。 目前,我们已将SP分为两部分,尽管无法说明如何解决问题,但似乎已解决了该问题。
数据库:MS SQL Server。
我有一个执行少量操作的SP-即根据某些状态将行插入3个表中,作为该SP的一部分被调用。
它是根据用户操作从我们的Web应用程序中调用的。
在某些情况下,一天几次会多次插入同一行(有时超过50次以上),并且每行中的值都相同,但如果您查看插入行的日期时间会有所不同几毫秒。因此,用户不太可能启动该操作。
此SP不在事务中运行或未带有任何锁,但是由于我们在Web应用程序上有许多并发用户正在调用此操作,因此它可能被并发多次调用。
我的问题是什么导致同一行多次插入?如果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