从数据库中检索的值不正确

时间:2013-08-19 19:33:33

标签: php mysql cron

情况:我创建了一个cron作业。这是为了将客户输入的订单添加到API。我将它设置为每隔一分钟运行一次。

问题:有时,当有太多挂单时,第二个cron作业在第一个结束之前被调用。这导致通过API发送重复订单。

解决方案:我在数据库中创建了一个名为cron_jobs的表。它有两列,ID和状态。当cron作业运行时,它会检查状态是否为0。如果status为0,则将状态更新为1.它完成其进程并再次将状态标记为0.如果作业的状态为1(表示它已在运行),并且再次命中,则操作为终止。

意外麻烦:此解决方案似乎在逻辑上是正确的。但是当我实施它时,结果令人震惊。作业运行时,其状态将更新。但是当再次调用它时,数据库仍然返回状态0并继续执行。我也使用了睡眠方法,以便我有足够的时间来研究这个问题。但是数据库总是返回不正确的值,而不是我使用phpmyadmin看到的值。

请不要认为我可能犯了一些愚蠢的错误。 在完全调用第一个实例之前,文件的第二个实例始终提取不正确的值。 看看我的代码:

<?php
$Output = mysql_fetch_assoc(mysql_query("select status from jobs where ID='1'"));
if($Output['status'] == '0')
{
    mysql_fetch_assoc(mysql_query("update jobs set status='1' where ID = '1'"));
    mysql_fetch_assoc(mysql_query("update jobs set invoked = invoked+1 where ID = '1'"));
    echo 'Executed';
}
else
{
    echo 'Error: Another cron job already in process. Operation terminated!';
    die();
}

/*I perform some lengthy tasks here*/

    /*Sleep function called to check whether another instance of the program works while this one is in progress */
    sleep(60);

    /*Task is complete. We are marking 0 as status so that another instance is allowed to work on.*/

    mysql_fetch_assoc(mysql_query("update jobs set status='0' where ID = '1'"));
?>

观察1 :如果我在另一台浏览器或另一台计算机上运行第二个实例,它会完美运行。

观察2 :我试图调查是否实际上被调用了几次。我在表中创建了另一列“No_Of_Times_Invoked”。我发现当我从同一个浏览器使用时,代码实际上失败了。

1 个答案:

答案 0 :(得分:1)

您的SELECT查询使用表格cron_jobs。每个其他查询都使用jobs。我相信您的SELECT查询失败,导致mysql_query()返回false

$Output = mysql_fetch_assoc(mysql_query("select status from cron_jobs where ID='1'"));

由于mysql_query()在此处返回falsemysql_fetch_assoc()也会返回false

if($Output['status'] == '0')

$Outputfalse。在PHP中,使用==时,可以进行类型转换。在这种情况下,$Output['status'] == '0'评估为true。 (请注意,$Output['status']null,但null == '0'评估为falsetype jugglingloose comparisons的欢乐。)

替换您的查询
SELECT `status` FROM jobs WHERE ID = '1'

它应该运行正常。

我建议在mysql_*()函数的返回值中添加一些错误检查(使用$returnValue === false),或者更好的是,切换到PDO


在评论中进行了一些讨论后更新

问题似乎是您正在使用浏览器进行测试。至少Firefox 23.0.1(我用于测试)在第一个请求完成之前不发送第二个请求。这可以解释您所看到的所有行为。新的浏览器或计算机将无法重新使用连接,因此在这种情况下它可以正常工作。

如果我从命令行启动脚本两次(相隔五秒),它就能正常工作:第二次运行输出Error: Another cron job already in process. Operation terminated!

请注意,PHP确实会抱怨每个mysql_fetch_assoc()函数调用周围的mysql_query("update ...")无效:

  

警告:mysql_fetch_assoc()要求参数1为资源,第7行的/test/test.php中给出布尔值