首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何防止SQL代理作业的并行运行

如何防止SQL代理作业的并行运行
EN

Database Administration用户
提问于 2020-12-19 11:27:42
回答 3查看 1.5K关注 0票数 4

设计一组作业的好方法是什么,使它们永远不能同时运行?

我正在寻找一个通用的概念,比如信号量,这样可以更容易地确保某些作业永远不会同时运行。

例如,我在想一个“信号表”。当作业开始时,它设置信号,在结束时,它重置信号。此外,每个作业都需要等待,直到信号被设置。(如何实现对CPU友好的等待?)然而,当作业崩溃时,必须有一个自动重置信号的解决方案,否则作业永远不会启动。

我们有4个工作,正在做各种更新,进口,计算。它们都是通过调度程序运行的,另外,在需要特殊运行的情况下,超级用户也可以手动启动其中的一些。但是,它们不应该同时运行,因为它通常会导致锁,甚至死锁,并且数据库不能正确地响应当时的用户。

编辑:这是一个数据仓库,它正在收集和整合来自多个外部数据源的数据。每个作业都负责另一个数据源,如下所示:

  • 作业#1每15分钟运行一次。
  • 工作2每3小时一次
  • 作业#3和作业#4每天运行一次,或者在超级用户启动时有额外的运行。
EN

回答 3

Database Administration用户

发布于 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

代码语言:javascript
复制
EXEC msdb.dbo.sp_help_job @Job_name = 'TheJobName'

您可以使用过程结果集的列current_execution_statuscurrent_execution_step来帮助您确定何时运行当前job是安全的。

还有一些系统job tables可能也有助于您进行查询,您可以在这个StackOverflow答案中阅读它们。

票数 4
EN

Database Administration用户

发布于 2020-12-21 05:28:28

如果使用的是,则可以根据分类器函数中的suser_name中的帐户将SQL作业专门分类为一个工作负载组。或者,每个相关作业的各个步骤都可以用作分类器函数中的app_name值。分配的工作负载组可以将GROUP_MAX_REQUESTS设置为1,因此一次只能在工作负载组中执行一个请求。

https://learn.microsoft.com/en-us/sql/t-sql/statements/create-workload-group-transact-sql?view=sql-server-ver15

票数 2
EN

Database Administration用户

发布于 2020-12-21 10:18:21

你对信号量表的建议是合理的。作为应用程序开发人员,它把处理步骤、作业、系统或硬件故障后的清理工作的所有责任都交给了您。通过使用内置函数服务提供商_getapplock,可以将所有这些工作传递给Server。

这与为防止写冲突而对行采取的共享锁和排他锁的功能完全相同。区别在于你可以给锁命名并决定它能保护什么。每个工作将获得一个步骤,在开始获得锁,在结束时释放它。如果由于另一个作业正在运行而无法获得锁,则可以选择在队列中等待或立即返回。在这两种情况下,作业都可以处理适当的操作。

如果当前持有锁的作业失败,Server将在其内置整理过程中自动释放锁。不需要额外的应用程序逻辑。下一个要运行的作业将可以自由获取锁并执行其处理。

票数 0
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/281854

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档