如何只有一个程序实例运行计划任务
本文关键字:运行 计划 任务 实例 程序 有一个 | 更新日期: 2024-07-10 20:00:03
我的软件在多台机器上针对一个数据库运行。
我希望每天在软件中执行一项任务,例如中午。
我如何确保此任务是:
- 每天只进行一次
- 无论当天哪台机器/用户碰巧在运行软件
- 不与软件的任何其他实例同时执行
在客户端执行此操作的问题是,您的用户可能有一天根本无法运行软件,或者在操作过程中可能遇到硬件故障(例如电源丢失),从而导致永久锁定。您无法保证任务的完整性,甚至无法保证任务会运行。
如果您需要确保它运行,而不管用户每天实际使用您的软件,这就有助于在数据库服务器上执行计划任务(适用于Windows和Linux/UNIX)。
创建一个执行任务的可执行文件,然后创建一个每天运行的计划任务。这样,只要数据库机器启动,您就可以获得一个始终运行的实例,并且您不必担心跨客户端跟踪作业执行情况。
好的,您现在说由于公司规则的原因,您不能在数据库框中运行计划任务。这是我要使用的方案:
- 为作业调度创建一个表。为每个作业指定一个运行日期/时间、作业开始时间(如果未开始,则为null)、进度字段以及任务所需的名称和其他信息
- 让每个客户每5分钟左右进行一次轮询,以运行查询来查找有过去日期的作业。选择行未锁定的第一个作业
- 锁定行并将"作业开始时间"字段更新为当前时间
- 执行任务,在作业完成时更新进度字段
- 成功时删除该行,否则将该行标记为"失败"
重要的部分是"作业开始的时间"字段,它允许客户端检查作业是否早就开始了(例如3小时),但从未完成,因此可以根据进度值重试或向用户发出警报。
您可以在数据库中使用带有单行的表。使用交易记录锁定包含上次更新日期的行。
每X分钟:
- 如果记录被锁定,则表示有人正在执行该工作。什么都不做
- 如果记录已过期且未锁定,请锁定它并执行此操作。如果失败,请解锁记录。如果成功,请使用当前日期更新记录
- 如果记录包含当前日期,则不执行任何操作
使用SQL Server的示例
如果您在事务中运行此操作,它将锁定来自其他客户端的行
UPDATE Test WITH (ROWLOCK)
SET UpdateDate = yourDate
WHERE PrimaryKey = yourkey