ورود

View Full Version : تعریف timeout برای استور پروسیجر



masoode
پنج شنبه 11 خرداد 1402, 14:06 عصر
سلام
من یک استور پروسیجر دارم که بعضی وقتها دچار Suspend میشه! هنوز هم علت آن را تشخیص نداده ام!
آیا میشه توی استور پروسیجر timeout گذاشت که اگر گیر کرد خطا بدهد و کار را متوقف کند؟ یا حداقل برای دستور EXEC یک جوری Timeout تعریف کنم؟

ShayanFiroozi
جمعه 12 خرداد 1402, 10:36 صبح
سلام ،


SET LOCK_TIMEOUT 1800;
SELECT @@LOCK_TIMEOUT AS [Lock Timeout];


توجه بفرمایین که تایم به میلی ثانیه هست ،
در ضمن اگر ممکنه کد پروسیجر رو هم ارسال کنین ، شاید مشکل از جای دیگست که Suspend میشه.

masoode
شنبه 13 خرداد 1402, 09:25 صبح
سلام ،


SET LOCK_TIMEOUT 1800;
SELECT @@LOCK_TIMEOUT AS [Lock Timeout];


توجه بفرمایین که تایم به میلی ثانیه هست ،
در ضمن اگر ممکنه کد پروسیجر رو هم ارسال کنین ، شاید مشکل از جای دیگست که Suspend میشه.

USE [Mana_Boresh_CNC1]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[INSERT_LantekData]
AS
BEGIN
DECLARE
@CustId int,@CustName nvarchar(255),@JobNo varchar(30), @LastDate datetime,@final int,
@ProjectId bigint,@JobId bigint,@RC varchar(max),@Ret int,
@LogText nvarchar(max)

BEGIN TRANSACTION
BEGIN TRY
select TOP(1) @CustId=ISNULL(tblCustomers.id,-1),@CustName=tbl.Name,@JobNo=tbl.JobRef,@LastDate= tbl.LastDate,@final=ISNULL(tbl.Final,0),@ProjectId =tbl.ProjectId,@JobId=tbl.JobId from (
select vwLantekLast.Name,JobRef,LastDate,Final,tblProject s.id ProjectId,tblLantekJobs.id JobId
from vwLantekLast,tblLantekJobs,tblProjects,(SELECT MAX(InsertDT) InsertDT,JobId from tblLantekFactorDetail group by JobId)FacDet
where vwLantekLast.JobRef=tblLantekJobs.JobNo AND FacDet.JobId=tblLantekJobs.id AND tblProjects.Id=tblLantekJobs.ProjectId AND LastDate>InsertDT
union
select *,CAST(0 as bit) Final,null ProjectId,null JobId
from vwLantekLast
where vwLantekLast.JobRef not in (select JobNo from tblLantekJobs) and
(LastDate>'2022-10-23' OR ((LastDate>'2022-03-21')AND(Name='MANA PERSHIA' OR Name='MANA KHADAMAT' OR Name='SEMSAR' OR Name='KWC')))
)tbl
left join tblCustomers on tblCustomers.CustomerNameLantek=tbl.Name COLLATE Arabic_CI_AS
where Final=0 AND LastDate<DATEADD(MI,-1,SYSDATETIME())
order by LastDate desc

IF @LastDate IS NOT NULL BEGIN
IF @CustId=-1 BEGIN
INSERT INTO tblCustomers(CustomerCode,CustomerName,CustomerNam eLantek)VALUES(
(SELECT MAX(CustomerCode)+1 FROM tblCustomers),@CustName,@CustName)
SELECT @CustId=@@IDENTITY
SET @LogText=N'Add Customer='+@CustName
EXECUTE @Ret=dbo.WriteLog @Description=@LogText
END

SELECT @ProjectId=T1.Id FROM tblProjects T1 LEFT JOIN tblLantekJobs T2 ON T1.Id=T2.ProjectId WHERE JobNo=@JobNo
IF @ProjectId IS NULL BEGIN
INSERT INTO tblProjects(RegTime,Name,CustomerId,UserId,OrderTi me,SheetCut,Brake,PipeCut,Weld,MaterialMana,Materi alCustomer,MaterialGet)VALUES(SYSDATETIME(),
@JobNo,@CustId,15,@LastDate,1,0,0,0,0,0,0)
SELECT @ProjectId=@@IDENTITY
SET @LogText=N'Add Project='+@JobNo
EXECUTE @Ret=dbo.WriteLog @Description=@LogText
END

SELECT @JobId=Id FROM tblLantekJobs WHERE JobNo=@JobNo
IF @JobId IS NULL BEGIN
INSERT INTO tblLantekJobs(InsertDateTime,JobNo,Name,ProjectId, ProvidedQuantity)VALUES(SYSDATETIME(),
@JobNo,@CustName,@ProjectId,
(SELECT SUM(DIS_NQ) FROM REM.CUT1401.dbo.[MMNN_MMOO_00000300] WHERE DIS_JobRef=@JobNo))
SELECT @JobId=@@IDENTITY
SET @LogText=N'Add Job='+@JobNo
EXECUTE @Ret=dbo.WriteLog @Description=@LogText
END
EXECUTE @RC = [dbo].[INSERT_LantekFactorDetailsAndMetrial] @JobNo
SET @LogText=N'Add Lantek Details='+@JobNo
EXECUTE @Ret=dbo.WriteLog @Description=@LogText
IF @RC<>'0' BEGIN
SET @LogText=N'Error in [INSERT_LantekFactorDetailsAndMetrial] Message='+@RC
EXECUTE @Ret=dbo.WriteLog @Description=@LogText,@LogTypeId=2
END
END
UPDATE tblVar SET Value=SYSDATETIME() WHERE Name='LastAlive'
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
SELECT ERROR_MESSAGE()
SET @LogText=ERROR_MESSAGE()
EXECUTE @Ret=dbo.WriteLog @Description=@LogText,@LogTypeId=2
END CATCH

END

masoode
شنبه 13 خرداد 1402, 09:38 صبح
سلام ،


SET LOCK_TIMEOUT 1800;
SELECT @@LOCK_TIMEOUT AS [Lock Timeout];


توجه بفرمایین که تایم به میلی ثانیه هست ،
در ضمن اگر ممکنه کد پروسیجر رو هم ارسال کنین ، شاید مشکل از جای دیگست که Suspend میشه.
من برای تست کد زیر را نوشتم. vwlogs شامل بیش از صد هزار رکورد است و نتیجه SELECT حدود 2 ثانیه طول میکشد. اما با استفاده از تایم اوت 10 میلی ثانیه ای خطایی نداد!! شاید اشتباه استفاده کرده ام!
SET LOCK_TIMEOUT 10
--SELECT @@LOCK_TIMEOUT AS [Lock Timeout]
select * from vwLogs

ShayanFiroozi
شنبه 13 خرداد 1402, 10:46 صبح
سناریو به چه شکل هست که شما باید همه بیش از صد هزار رکورد رو Fetch کنین ؟
چرا با WHERE فیلتر نمیکنین ؟

ShayanFiroozi
شنبه 13 خرداد 1402, 10:54 صبح
پیشنهاد میکنم قسمت های مربوط به Logging و عملیات غیر ضروری رو فعلا غیر فعال کنین ، تا راحتر تر بشه کد رو Trace کرد.

masoode
شنبه 13 خرداد 1402, 11:14 صبح
این فقط تست بود که ببینم LOCK_TIMEOUT چه جوری کار می کند. که خطایی نداد! اجرای کوئری من 2 ثانیه طول میکشد و LOCK_TIMEOUT را برابر 10 میلی ثانیه گذاشتم اما خطا نداد!
SET LOCK_TIMEOUT 10
--SELECT @@LOCK_TIMEOUT AS [Lock Timeout]
select * from vwLogs

استور پروسیجر را به طور خلاصه بخوام براتون توضیح بدهم
در قسمتی که با TOP(1) شروع میشود. از ویو vwLantekLast جدیدترین رکورد را که قبلا در جدول tblLantekJobs اینسرت یا آپدیت نشده است را انتخاب میکند
البته vwLantekLast از جداولی استخراج میشود که با Linked Servers از دیتابیسی دیگر به آنها ریموت شده ایم. البته دیتابیس اول و دوم روی یک سرور با دو اینستنس است
در قسمت بعدی در صورتی که در قسمت قبل رکوردی یافت شده باشد در جدولهای مربوط به آنها اینسرت می کند.
استور پروسیجر INSERT_LantekFactorDetailsAndMetrial هم یک مجموعه داده هایی را از دیتابیس دوم به دیتابیس اول اینسرت میکند.
کل داده هایی که در هر بار فراخوانی این استور پروسیجر insert میشود معمولا زیر 50 رکورد است. البته select اول حدود 2 ثانیه زمان میبرد.
این استور پروسیجر هر 30 ثانیه یک بار در یک Windows Service اجرا میشود