我刚刚有一个计划的 SQL Server 作业运行时间比正常情况要长,我真的可以通过设置超时来在一定时间长度后停止它。
我可能对此有点盲目,但我似乎找不到一种为作业设置超时的方法。 有谁知道方法吗?
谢谢
我们做了类似下面的代码作为夜间作业处理子系统的一部分 - 它实际上比现实中的更复杂;例如,我们正在处理多个相互依赖的作业集,并从配置表中读取作业名称和超时值 - 但这抓住了这个想法:
DECLARE @JobToRun NVARCHAR(128) = 'My Agent Job'
DECLARE @dtStart DATETIME = GETDATE(), @dtCurr DATETIME
DECLARE @ExecutionStatus INT, @LastRunOutcome INT, @MaxTimeExceeded BIT = 0
DECLARE @TimeoutMinutes INT = 180
EXEC msdb.dbo.sp_start_job @JobToRun
SET @dtCurr = GETDATE()
WHILE 1=1
BEGIN
WAITFOR DELAY '00:00:10'
SELECT @ExecutionStatus=current_execution_status, @LastRunOutcome=last_run_outcome
FROM OPENQUERY(LocalServer, 'set fmtonly off; exec msdb.dbo.sp_help_job') where [name] = @JobToRun
IF @ExecutionStatus <> 4
BEGIN -- job is running or finishing (not idle)
SET @dtCurr=GETDATE()
IF DATEDIFF(mi, @dtStart, @dtCurr) > @TimeoutMinutes
BEGIN
EXEC msdb.dbo.sp_stop_job @job_name=@JobToRun
-- could log info, raise error, send email etc here
END
ELSE
BEGIN
CONTINUE
END
END
IF @LastRunOutcome = 1 -- the job just finished with success flag
BEGIN
-- job succeeded, do whatever is needed here
print 'job succeeded'
END
END
这是一份什么样的工作?您可能需要考虑将整个作业放入 While 循环内的 TSQL 脚本中。要检查的条件显然是当前时间和作业开始时间之间的时间差。
拉杰
您可以使用第二个作业来监控第一个作业的进度。
我使用以下存储过程:
CREATE OR ALTER PROCEDURE MonitorJob
@jobname NVARCHAR(128), @timeout INT = 3600
AS
BEGIN
SET NOCOUNT ON;
DECLARE @canceltime DATETIME = DATEADD(SECOND, @timeout, GETDATE())
DECLARE @T TABLE (
session_id int,
job_id uniqueidentifier,
job_name sysname,
run_requested_date datetime NULL,
run_requested_source sysname NULL,
queued_date datetime NULL,
start_execution_date datetime NULL,
last_executed_step_id int NULL,
last_executed_step_date datetime NULL,
stop_execution_date datetime NULL,
next_scheduled_run_date datetime NULL,
job_history_id int NULL,
message nvarchar(1024) NULL,
run_status int NULL,
operator_id_emailed int NULL,
operator_id_netsent int NULL,
operator_id_paged int NULL
)
WHILE @canceltime > GETDATE() BEGIN
WAITFOR DELAY '00:01:00'
INSERT @T EXEC msdb.dbo.sp_help_jobactivity @job_name = @jobname
IF EXISTS(SELECT 1 FROM @T WHERE stop_execution_date IS NOT NULL)
RETURN; -- Job has stopped within timeout, success!
DELETE FROM @T
END
-- Job has exceeded timeout
EXEC msdb.dbo.sp_stop_job @jobname
-- Consider RAISERROR to signal failure or send a mail
END
然后,您可以创建一个监视作业,该作业使用主作业的作业名称和超时来执行存储过程。然后,将此监控作业添加为主要作业的第一步。
另一种更简单的方法是:
在您的主要作业中,在开始时启动监控作业,并在结束时停止它。
在监控作业中,等待指定的超时,然后停止主作业。