-1

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

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

我怎样才能确保这个任务是:

  • 每天只执行一次,
  • 无论当天哪台机器/用户碰巧运行该软件,都执行,并且
  • 没有与软件的任何其他实例同时执行?
4

2 回答 2

2

在客户端这样做的问题是您的用户可能一天都不会运行该软件,或者他们可能在运行过程中遭受硬件故障(例如断电),从而导致永久锁定行。你不能保证任务的完整性,你甚至不能保证任务会运行。

如果您需要确保无论用户每天实际使用您的软件如何,它都能运行,这适用于数据库服务器上的计划任务(适用于WindowsLinux / UNIX )。

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


好的,所以您现在说由于公司规则,您无法在数据库框上运行计划任务。这是我要使用的方案:

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

重要的部分是“作业开始时间”字段,它允许客户端检查作业是否在很久以前(例如 3 小时)开始但从未完成,因此可以重试或提醒用户,具体取决于进度值.

于 2012-07-25T08:20:47.283 回答
1

您可以在数据库中使用具有单行的表。使用事务来锁定包含最后更新日期的行。

每 X 分钟:

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

使用 SQL Server 的示例

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

UPDATE Test WITH (ROWLOCK)
SET UpdateDate = yourDate
WHERE PrimaryKey = yourkey
于 2012-07-25T08:21:41.307 回答