设计一组作业的好方法是什么,使它们永远不能同时运行?
我正在寻找一个通用的概念,比如信号量,这样可以更容易地确保某些作业永远不会同时运行。
例如,我在想一个“信号表”。当作业开始时,它设置信号,在结束时,它重置信号。此外,每个作业都需要等待,直到信号被设置。(如何实现对CPU友好的等待?)然而,当作业崩溃时,必须有一个自动重置信号的解决方案,否则作业永远不会启动。
我们有4个工作,正在做各种更新,进口,计算。它们都是通过调度程序运行的,另外,在需要特殊运行的情况下,超级用户也可以手动启动其中的一些。但是,它们不应该同时运行,因为它通常会导致锁,甚至死锁,并且数据库不能正确地响应当时的用户。
编辑:这是一个数据仓库,它正在收集和整合来自多个外部数据源的数据。每个作业都负责另一个数据源,如下所示:
发布于 2020-12-19 13:09:24
除了评论之外,这里还有一些东西可以用来完成您想要做的事情(因为我不喜欢为锁定系统重新发明轮子)。
您可以使用system stored procedure msdb.dbo.sp_帮助_工作来确定其他jobs是否正在运行,作为每个job中的第一步。然后,在运行另一个job时,您可以选择它接下来要采用的逻辑,比如结束job (如果它是按常规计划进行的),或者使用WAITFOR DELAY ('00:00:01') -- Sleeps for 1 second实现模拟睡眠,您可以在WHILE循环中重新检查job状态。
您可以通过传入sp_help_job名称来调用job:
EXEC msdb.dbo.sp_help_job @Job_name = 'TheJobName'您可以使用过程结果集的列current_execution_status和current_execution_step来帮助您确定何时运行当前job是安全的。
还有一些系统job tables可能也有助于您进行查询,您可以在这个StackOverflow答案中阅读它们。
发布于 2020-12-21 05:28:28
如果使用的是,则可以根据分类器函数中的suser_name中的帐户将SQL作业专门分类为一个工作负载组。或者,每个相关作业的各个步骤都可以用作分类器函数中的app_name值。分配的工作负载组可以将GROUP_MAX_REQUESTS设置为1,因此一次只能在工作负载组中执行一个请求。
发布于 2020-12-21 10:18:21
你对信号量表的建议是合理的。作为应用程序开发人员,它把处理步骤、作业、系统或硬件故障后的清理工作的所有责任都交给了您。通过使用内置函数服务提供商_getapplock,可以将所有这些工作传递给Server。
这与为防止写冲突而对行采取的共享锁和排他锁的功能完全相同。区别在于你可以给锁命名并决定它能保护什么。每个工作将获得一个步骤,在开始获得锁,在结束时释放它。如果由于另一个作业正在运行而无法获得锁,则可以选择在队列中等待或立即返回。在这两种情况下,作业都可以处理适当的操作。
如果当前持有锁的作业失败,Server将在其内置整理过程中自动释放锁。不需要额外的应用程序逻辑。下一个要运行的作业将可以自由获取锁并执行其处理。
https://dba.stackexchange.com/questions/281854
复制相似问题