0


我已经建模了作业,它在 sql 表中的依赖关系:作业(id、detail、exit_code)依赖关系(job_id、dependenet_job_id)

例如:如果作业 1 依赖于 2 和 3,则表将具有以下内容:
作业
1 "job1" NULL
2 "job2" NULL
3 "job3" NULL
4 "job4" NULL

依赖项
1 2
1 3

现在我需要找到接下来可以运行的工作。在上述情况下,可以运行 2,3 和 4,因为它们没有任何依赖关系。只有当 2 和 3 成功完成(退出代码 = 0)时,1 才能运行。

这些表可以有数百个作业和多级依赖关系。我有查询使用左外连接获得没有依赖关系的工作。但是无法找到已成功完成依赖项的作业。

谢谢。

4

2 回答 2

0

查询形式为“选择没有未完成的依赖作业的作业”

Select
  *
from
  jobs j
where
  not exists (
    select
      'x'
    from
      dependencies d
        inner join
      jobs j2
        on d.dependent_job_id = j2.id
    where
      j.id = d.job_id and (
        j2.exit_code is null or -- job hasn't completed successfully
        j2.exit_code != 0
      )
  );

Example SQLFiddle

于 2013-11-02T23:36:39.880 回答
0

对于“嵌套”依赖项(即job1 依赖于job2,job2 依赖于job3),您需要一个递归查询,MySQL 不支持该查询。

您可以查看这篇文章,了解如何重新设计表以处理递归。

您可以做的另一件事是:

每当作业完成时,它的依赖关系就会被删除或停用(您active在依赖关系表中添加一个布尔列)

这样,您可以运行

SELECT jobs.* FROM jobs
    LEFT JOIN depends ON (jobs.id = depends.parent_id AND depends.active = TRUE)
    WHERE depends.child_id IS NULL
          AND jobs.started = FALSE;

这将返回所有尚未启动但没有活动依赖项的作业。

一旦你选择了一个工作,你运行

UPDATE jobs SET started=TRUE WHERE id = @JOB_ID;

当它完成时,

UPDATE jobs SET exitcode=@EXIT_CODE WHERE id = @JOB_ID;
UPDATE dependencies SET active = FALSE WHERE child_id = @JOB_ID;
-- or
DELETE FROM dependencies WHERE child_id = @JOB_ID;
于 2013-11-02T23:54:29.547 回答