PHP、MySQL和Cron Jobs-执行查询存储所有要启动或按顺序执行的行


PHP, MySQL and Cron Jobs - Does a query store all rows to start, or go through sequentially?

我有一个MySQL表:

Col 1 | Col 2 | Col 3 | Status
 ...  |  ...  |  ...  |  0
 ...  |  ...  |  ...  |  1
 ...  |  ...  |  ...  |  2
etc

重要的是,表中要有最新的信息,因此每分钟都会运行一个cron作业来更新表。

Status列用于存储行是否需要更新或当前正在更新。如果该行需要更新,则状态为0。如果行当前正在更新,则状态为1。如果该行已经更新,则状态为2。

一旦所有行的状态都为2,它们就会全部重置为0,然后重新开始处理。

cron作业每分钟运行一次,但有时更新一行可能需要几分钟,这意味着多个cron作业将同时运行。

我的问题是,如果我有这样的查询:

UPDATE * FROM table WHERE status=0

查询是否一次通过一个,然后进入下一个0?还是查询先查看所有行,然后存储它最终将访问的行?

示例

假设下表已设置:

Col 1 | Col 2 | Col 3 | Status
 ...  |  ...  |  ...  |  0
 ...  |  ...  |  ...  |  0
 ...  |  ...  |  ...  |  0
 ...  |  ...  |  ...  |  0
 ...  |  ...  |  ...  |  0

在t=0时,第一个cron作业(cj1)开始。它进入第一行,并将状态设置为1。

Col 1 | Col 2 | Col 3 | Status
 ...  |  ...  |  ...  |  1
 ...  |  ...  |  ...  |  0
 ...  |  ...  |  ...  |  0
 ...  |  ...  |  ...  |  0
 ...  |  ...  |  ...  |  0

这个过程需要一分钟以上的时间,因此第二个cron作业(cj2)从t=1m开始。

cj2看到第一行已经在更新,因此转到第二行。

Col 1 | Col 2 | Col 3 | Status
 ...  |  ...  |  ...  |  1
 ...  |  ...  |  ...  |  1
 ...  |  ...  |  ...  |  0
 ...  |  ...  |  ...  |  0
 ...  |  ...  |  ...  |  0

假设cj2正忙于更新该行几分钟。当cj1完成第一行时,它会跳到第三行吗,因为它看到第2行的状态为1?还是cj2会转到第二行,因为在调用查询时,它最初的状态为0?

由于使用InnoDB,默认情况下,每个查询都将作为事务执行。所以当你做时

UPDATE table
SET <whatever>
WHERE status = 0

它将锁定与CCD_ 2值匹配的所有行。如果执行类似查询的其他进程试图访问这些行中的任何一行,它们将被阻止。

它执行此操作的具体方式取决于status列上是否有索引。如果有,它只需锁定该索引条目,然后更新它引用的所有行

如果没有索引,则必须按顺序遍历数据库。每当它包含一个具有status = 0的行时,它都会锁定该行,然后更新它。其他客户端可能会以不同的顺序扫描数据库,因此他们可能会在查询到达数据库之前看到该查询将更新的行。如果他们在更新其他列的同时更新status,那么你应该不会有问题,因为当这个过程到达那些行时,它们将不再符合CCD_ 6标准。

这取决于您的实现方式。如果完成了对行的更新。。一个cron作业去获取下一个要更新的1结果(状态=0),然后只处理一条记录,就可以实现您想要的目标。

如果您将获取状态为0的所有结果,然后将其存储到$resuls变量中并在其上启动循环,则cron作业1将在不知道cron 2已经处理的情况下重新处理记录2,因为$result变量没有更新的信息。