PHP卷曲时序不匹配

时间:2010-06-01 18:30:14

标签: php curl

我正在运行一个PHP脚本:

  1. 查询本地数据库以检索金额
  2. 执行curl语句以使用上述金额+ x
  3. 更新外部数据库
  4. 再次查询本地数据库以插入反映curl语句已执行的新行。
  5. 我遇到的一个问题是curl语句需要2-4秒才能执行,所以我有两个不同的用户来自同一个公司同时运行相同的脚本,curl命令的执行时间可能导致外部数据库中应更新的内容不匹配。这是因为curl语句尚未从第一个用户返回...所以第二个用户正在处理不正确的数字。

    我不确定这里的最佳选择,但基本上我需要防止两个或多个curl语句同时运行。

    我想在数据库中存储一个值,表示当时正在执行curl语句,并阻止任何其他curl语句在完成之前运行。一旦执行了第一个curl语句,就会更新数据库标志并运行下一个。如果此字段被“锁定”,那么我可以遍历代码并休眠(5)秒,然后再次检查标志是否已重置。如果在(3)循环之后,则自动重置标志(我从未见过卷曲花费的时间超过5秒)并继续处理。

    还有其他(更优雅)的方式来接近这个吗?

3 个答案:

答案 0 :(得分:2)

您可以将flock与任意文件一起使用。这样,第二个脚本将阻塞,直到它可以获得锁定。

$lockfile = 'foo.bar';
$fd = fopen($lockfile, "w");
if (flock($fd, LOCK_EX)) {
    do_your_stuff();
}
else
    die("error"); //should not happen; flock should block until the lock is acquired

fclose($fd);

编辑:

PHP不是Java EE,没有简单的方法来实现分布式事务。

答案 1 :(得分:0)

您需要的是Concurrency control。许多人花了很多时间和精力研究这个问题。

这个问题并不像你希望的那么简单。一些论坛引擎( cough Stackoverflow cough )也实现了与此类似的东西,因此它可以按创建顺序(未发布)显示帖子。这是通过创建随机令牌来完成的,最终用户必须使用该令牌来通知服务器它仍然处于活动状态并且仍在不时地处理当前正在编辑/添加的记录。最常见的问题是连接超时和用户超时问题。通过让客户端发送心跳来解决连接超时问题(在Web上这通常是通过发出HTTP请求来通知服务器连接仍然是 alive - open)定期到服务器;如果客户端长时间停止发送 hearbeats ,则认为服务器已将其超时。同时,客户端还应该知道心跳是否已到达服务器,并且应该考虑在连接超时的情况下该怎么做。当用户简单地锁定记录并且长时间离开计算机时,还存在用户超时的情况。在这种情况下,客户端和服务器都应该知道记录已被锁定但很长一段时间没有被使用(编辑)的事实,他们都应该采取行动。

问题可能看似简单,可以用一句话来表达,但答案很复杂,取决于很多因素。

答案 2 :(得分:0)

curl支持使用curl_multi_exec()对N个资源的并行请求。如果你想按顺序进行这些调用(其中有多个curl_ *调用)并使上述语句成为原子操作,则在使用时不要使用curl_multi。

如果您访问更新的数据库记录不能(或不应该)由多个用户同时访问,那么您应该考虑从数据库服务器获取锁定/事务。 / p>

使用伪事务机制以及将记录标记为“已锁定”的列可能对您有所帮助,但我无法确定(有一种使用时间戳的伪事务方法,您可以谷歌获取更多信息)。