【问题标题】:SQL Agent: Set a Max Execution TimeSQL 代理:设置最大执行时间
【发布时间】:2011-03-11 21:06:18
【问题描述】:

下午。我有几个 SQL 代理作业在 MS 2K8 BI 服务器上运行,其中一些每天运行,另一些每小时运行一次,每两分钟运行一次(另一个进程的心跳监视器)。还有一个应用程序可以每隔几分钟全天候导入数据。有时更新和报告的某些组合会发生冲突,导致其中一个或另一个挂起半小时或更长时间,而不是通常的 60 秒。

虽然我需要了解这些竞争条件的根源,但同时我想将某些作业设置为在五分钟后自动终止。我可以在 SSIS 或 Windows 计划任务中执行此操作,但在 SQL 代理中看不到任何方法。这可能吗,还是我需要将任务包装在 SSIS 包中才能获得这种控制?


仅供参考,这是我最终使用的 SQL 代理作业:

DECLARE @Cancelled BIT
EXEC dbo.CancelJob @JobName = 'ETL - Daily', @Cancelled = @Cancelled OUT

IF @Cancelled = 1
    BEGIN
    DECLARE @Success INT
    EXEC @Success = msdb..sp_send_dbmail
        @profile_name = 'Reporting',
        @recipients = 'reporting@mycompany.com',
        @subject = 'Cancelled Daily ETL'
    IF @Success <> 0 RAISERROR('An error occurred while attempting to send an e-mail.', 16, @Success)
    END

...这是CancelJob背后的代码:

CREATE PROCEDURE dbo.CancelJob(@JobName VARCHAR(100), @OwnerName VARCHAR(100) = NULL, @Cancelled BIT OUT)
AS BEGIN
    IF @OwnerName IS NULL SET @OwnerName = SUSER_NAME()
    SET @Cancelled = 0

    CREATE TABLE #JobInfo
        ( 
        Job_ID  UNIQUEIDENTIFIER,
        Last_Run_Date   INT,
        Last_Run_Time   INT,
        Next_Run_Date   INT,
        Next_Run_Time   INT,
        Next_Run_Schedule_ID    INT,
        Requested_To_Run    INT,
        Request_Source  INT,
        Request_Source_ID   VARCHAR(100),
        Running INT,  -- This is the only field we want (sigh)
        Current_Step    INT,
        Current_Retry_Attempt   INT,
        State   INT
        )
    INSERT INTO #JobInfo
        EXEC xp_sqlagent_enum_jobs 1, @OwnerName

    DECLARE @Running INT = (SELECT Running FROM #JobInfo AS JI INNER JOIN msdb..sysjobs_view AS J ON JI.Job_ID = J.job_id WHERE J.name = @JobName)
    IF @Running = 1
        BEGIN
        BEGIN TRY
            EXEC msdb..sp_stop_job @job_name = @JobName
            SET @Cancelled = 1
        END TRY
        BEGIN CATCH
            -- If an error occurs, it is *probably* because the job finished before we could cancel it, which is fine
        END CATCH
        END
END
GO

xp_sqlagent_enum_jobs 是避免无法捕获错误的诀窍。

【问题讨论】:

    标签: sql-server sql-server-agent


    【解决方案1】:

    我从来不需要经常这样做,因此可能会有更好的长期解决方案,但我创建了第二份工作以在我必须执行此任务的极少数情况下停止第一份工作。我只是使用 sp_stopjob 过程来执行此操作。

    【讨论】:

    • 我的第一个想法是,这将需要为每个作业创建一个邪恶的双胞胎,计划在第一个作业之后运行 X 分钟,但更好的是调用 msdb..sp_stop_job 在 开始每个重要工作,杀死任何其他可能干扰即将开始的工作的正在运行的工作。不错。谢谢,道格!
    • 如果作业未运行,sp_stop_job 似乎会引发无法捕获的异常(WTF!?)。我的解决方法是将停止放在作业中的一个单独步骤中,并使用“转到下一步”的“出错”操作。显而易见的解决方案是在尝试终止作业之前检查作业是否正在运行,但 AFAIK sp_help_job 是了解作业当前是否正在运行的唯一方法,它不能与 INSERT EXEC 一起使用。谁有更好的主意?
    猜你喜欢
    • 1970-01-01
    • 2011-07-04
    • 2013-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-29
    • 2011-01-13
    相关资源
    最近更新 更多