SQL Server 代理作业超时

问题描述 投票:0回答:3

我刚刚有一个计划的 SQL Server 作业运行时间比正常情况要长,我真的可以通过设置超时来在一定时间长度后停止它。

我可能对此有点盲目,但我似乎找不到一种为作业设置超时的方法。 有谁知道方法吗?

谢谢

sql-server sql-server-2005 timeout scheduling sql-server-agent
3个回答
13
投票

我们做了类似下面的代码作为夜间作业处理子系统的一部分 - 它实际上比现实中的更复杂;例如,我们正在处理多个相互依赖的作业集,并从配置表中读取作业名称和超时值 - 但这抓住了这个想法:

    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

2
投票

这是一份什么样的工作?您可能需要考虑将整个作业放入 While 循环内的 TSQL 脚本中。要检查的条件显然是当前时间和作业开始时间之间的时间差。

拉杰


0
投票

您可以使用第二个作业来监控第一个作业的进度。

我使用以下存储过程:

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

然后,您可以创建一个监视作业,该作业使用主作业的作业名称和超时来执行存储过程。然后,将此监控作业添加为主要作业的第一步。

另一种更简单的方法是:

在您的主要作业中,在开始时启动监控作业,并在结束时停止它。

在监控作业中,等待指定的超时,然后停止主作业。

© www.soinside.com 2019 - 2024. All rights reserved.