sql - 如何处理 sp_job_start 的错误?
问题描述
我有不同的触发器来启动工作。有时可以触发多个触发器同时启动这项工作,并且我最初检查该工作是否运行不正常。
DECLARE @JobCount NUMERIC
SET @JobCount = (SELECT COUNT(*)
FROM msdb.dbo.sysjobactivity ja
JOIN msdb.dbo.sysjobs j
ON ja.job_id = j.job_id
WHERE j.name = 'JobName'
AND ja.start_execution_date IS NOT NULL
AND ja.stop_execution_date IS NULL)
IF @JobCount = 0
BEGIN
EXEC msdb.dbo.sp_start_job
'JobName'
END
这是触发器的底部,但如果触发器是同时启动的,它仍然会出现错误Error: Request to run job JobName refused because the job is already running from a request by User
。BEGIN TRY/CATCH 在这里不起作用。我知道在 Oracle 中,当 OTHERS 为 NULL 时您可能会遇到异常 -如果发生错误,我可以在这里做些什么来忽略错误?我知道这项工作仍在运行,我只是不想产生错误。
谢谢
编辑:黑客解决方法是添加 WAITFOR DELAY '00:00:01' 但也可以接受其他建议
解决方案
通过让多个触发器调用作业,您已经引入了竞争条件,因此导致竞争的相同触发器不太可能解决它。你需要一个外部观察者。
你可以试试...
创建一个新表,例如:
CREATE TABLE JobControl
(
Id INT IDENTITY(1,1) PRIMARY KEY,
DateCreated DATETIME DEFAULT CURRENT_TIMESTAMP
)
更改您的触发器,以便它们在此表中插入一行而不是调用该作业。
创建一个每n秒运行一次的第二个作业(或者如果您愿意,可以不断循环)。该作业检查JobControl
表中的行。如果找到行(通过删除它们),它将运行主作业(如果它尚未运行)。如果它从该表中删除了行,并且事实证明该作业已经在运行,它将中止并将行放回以供下次使用。
如:
SET NOCOUNT ON
DECLARE @MYID UNIQUEIDENTIFIER, @rowsDeleted INT
SELECT @MYID=JOB_ID FROM MSDB.DBO.SYSJOBS WHERE NAME='JobName'
CREATE TABLE #enum_job
(
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,
Current_Step INT,
Current_Retry_Attempt INT,
State INT
)
IF @MYID IS NOT NULL
BEGIN
BEGIN TRAN
-- delete all rows in table, capture row count
DELETE J
FROM JobControl J
SET @rowsDeleted=@@ROWCOUNT
-- check running jobs
INSERT INTO #enum_job
EXEC master.dbo.xp_sqlagent_enum_jobs 1, NULL
-- if the job isn't running, and we had rows to delete, run the job
IF EXISTS (SELECT 1 FROM #enum_job WHERE Job_ID=@MYID AND Running=0) AND @rowsDeleted>0
BEGIN
EXEC msdb.dbo.sp_start_job 'JobName'
END
-- if the job is already running, and we had rows to delete, roll back
IF EXISTS (SELECT 1 FROM #enum_job WHERE Job_ID=@MYID AND Running=1) AND @rowsDeleted>0
BEGIN
ROLLBACK TRAN
END
-- if the transaction is still open, commit it
IF @@TRANCOUNT>0 COMMIT TRAN
END
推荐阅读
- bash - 如何在 grep 输出的每一行添加时间戳?
- java - 我的 NFC 扫描应用程序仅在 NFC 类型 2 时启动
- c# - C#/.NET/“未定义或导入预定义类型‘System.Object’”/“找不到类型或命名空间名称‘System’”
- c++ - (double) 和 double() 的区别
- scala - 如何为空的不变集合(例如 Set)推断正确的元素类型
- java - 使用现有证书、中间文件和远程创建的签名,使用 itextpdf for Java 对 PDF 进行两步签名
- javascript - 如何使用 jquery 选择动态创建的选项?
- google-apps-script - 自动创建电子表格,由下拉菜单中的新选择触发
- python - 如何使用 dtype ndarray 和数据框删除 DataFrame 列
- c# - 等待退出时进程有时会挂起