1

我有一张桌子JOB。它具有以下列:cycle_id, job_id, status

每个周期执行 7 个作业。所以cycle_idjob_id形成复合主键。

status 列可以有以下值:WAITING_TO_START, RUNNING. COMPLETED.

每个作业都是一个 cron 作业。每个工作都是不同人的责任,所以为了同步每个人,我正在使用数据库表 JOB。每个作业都侦听 JOB 表并观察它是否存在其 job_id 和状态为“WAITING_TO_START”的行。因此,每当作业状态更改为 COMPLETED 时,我想要什么,下一个作业行的创建与cycle_id更新的作业相同,job_id 作为更新的作业的 id + 1,状态为“WAITING_TO_START”。所以我为此创建了一个触发器:

DELIMITER $$

CREATE TRIGGER start_new_job
AFTER UPDATE ON job
FOR EACH ROW
BEGIN
IF NEW.status = 'COMPLETED' AND OLD.job_id <=6 THEN
   INSERT INTO job(cycle_id, job_id, status) VALUES (OLD.cycle_id, OLD.job_id+1, 'WATING_TO_START');
END IF;
END$$
DELIMITER ;

但是当我对 JOB 表执行更新时,出现以下错误:

UPDATE job SET status='COMPLETED' WHERE cycle_id=1 AND job_id=1;

错误 1442 (HY000):无法更新存储函数/触发器中的表“作业”,因为它已被调用此存储函数/触发器的语句使用。

那么有没有办法实现同步。我不希望每个工作都用下一个工作的 ID 创建一行。我希望它自动处理。这个触发器可以用不同的方式编写还是我应该使用其他机制。

4

1 回答 1

1

您将无法从触发器插入到同一个表中。我会用程序替换您的触发器,然后通过该程序引导所有状态更新:

CREATE PROCEDURE UpdateJobStatus(jobId INT, NewStatus NVARCHAR(50))
BEGIN
  UPDATE job
     SET `Status` = NewStatus 
     WHERE job_id = jobId;

  IF NewStatus = 'COMPLETED' AND jobId <=6 THEN
    INSERT INTO job(cycle_id, job_id, status) 
       SELECT cycle_id, job_id+1, 'WATING_TO_START'
       FROM job 
       WHERE job_id = jobId;
  END IF;
END;

Sql 小提琴在这里

尽管该过程需要对您的代码进行一些修改(即您需要调用该过程而不是直接更新数据),但该过程的好处是更明显 - 触发器在后台自动执行操作可能不直观。

于 2015-05-31T10:02:11.243 回答