如何只有一个程序实例运行计划任务

本文关键字:运行 计划 任务 实例 程序 有一个 | 更新日期: 2024-07-10 20:00:03

我的软件在多台机器上针对一个数据库运行。

我希望每天在软件中执行一项任务,例如中午。

我如何确保此任务是:

  • 每天只进行一次
  • 无论当天哪台机器/用户碰巧在运行软件
  • 不与软件的任何其他实例同时执行

如何只有一个程序实例运行计划任务

在客户端执行此操作的问题是,您的用户可能有一天根本无法运行软件,或者在操作过程中可能遇到硬件故障(例如电源丢失),从而导致永久锁定。您无法保证任务的完整性,甚至无法保证任务会运行。

如果您需要确保它运行,而不管用户每天实际使用您的软件,这就有助于在数据库服务器上执行计划任务(适用于Windows和Linux/UNIX)。

创建一个执行任务的可执行文件,然后创建一个每天运行的计划任务。这样,只要数据库机器启动,您就可以获得一个始终运行的实例,并且您不必担心跨客户端跟踪作业执行情况。


好的,您现在说由于公司规则的原因,您不能在数据库框中运行计划任务。这是我要使用的方案:

  1. 为作业调度创建一个表。为每个作业指定一个运行日期/时间、作业开始时间(如果未开始,则为null)、进度字段以及任务所需的名称和其他信息
  2. 让每个客户每5分钟左右进行一次轮询,以运行查询来查找有过去日期的作业。选择行未锁定的第一个作业
  3. 锁定行并将"作业开始时间"字段更新为当前时间
  4. 执行任务,在作业完成时更新进度字段
  5. 成功时删除该行,否则将该行标记为"失败"

重要的部分是"作业开始的时间"字段,它允许客户端检查作业是否早就开始了(例如3小时),但从未完成,因此可以根据进度值重试或向用户发出警报。

您可以在数据库中使用带有单行的表。使用交易记录锁定包含上次更新日期的行。

每X分钟:

  • 如果记录被锁定,则表示有人正在执行该工作。什么都不做
  • 如果记录已过期且未锁定,请锁定它并执行此操作。如果失败,请解锁记录。如果成功,请使用当前日期更新记录
  • 如果记录包含当前日期,则不执行任何操作

使用SQL Server的示例

如果您在事务中运行此操作,它将锁定来自其他客户端的行

UPDATE Test WITH (ROWLOCK)
SET UpdateDate = yourDate
WHERE PrimaryKey = yourkey