2013-03-23 71 views

回答

-1

这取决于用例。

如果您只在一台服务器上,请使用锁定文件。

function doSomething() { 
    $file = /temp/path/somthing.lock; 
    if (file_exists($file)) { 
    return false; 
    } 
    touch($file); 
    // Safely mess with things 
    unlink($file); 
} 

如果您有多个网络服务器,例如在负载均衡器的后面,同样的事情可以通过在mysql中使用表来完成。

function doSomething() { 
    $query = "SELECT * FROM locks WHERE name='something'"); 
    $res = mysqli_query($query); 
    if (mysql_num_rows($res) > 0) { 
    return false; 
    } 
    $query = "INSERT INTO locks (name) VALUES ('something')"; 
    mysqli_query($query); 
    // Safely mess with things 
    $query = "DELETE FROM locks WHERE name='something'"); 
    mysqli_query($query); 
} 

Memcache是​​多机支持的另一个明显的候选人。

您不应该使用ACP,因为它仅用于缓存。这意味着当ACP存储被删除时您无法控制,这可能随时发生。

您也可以使用信号量,但是如果您使用多个服务器,则与锁定文件相同的警告也适用。

我会建议创建lock($key),is_locked($key)release($key)函数,然后在整个项目中宗教地使用它们。这样你就可以开始使用锁定文件(快速实现),但随后升级到更好的东西,而无需编辑其余的代码。如果你想变得很花哨,你可以将它们作为一个记录器对象的方法来实现,并将它们放入代码的已知位置。

+0

Tnx的例子,但我怕他们受竞争条件? http://en.wikipedia.org/wiki/Race_condition – 2013-03-23 15:11:40

+0

嗯,是的,从某种意义上说,他们是。然而,这不是因为这些例子,而是IP协议的副作用,因此没有对时间进行保证。您可以做的最好的做法是阻止多个请求通过。 – cmc 2013-03-25 14:59:59

+0

@cmc什么? IP的网站效应?对于MySQL,您只需在'locks.name'上拥有一个UNIQUE索引,并且成功创建该记录的第一个客户端可以保留该锁。任何进一步的请求都将导致重复的密钥错误。 – Shi 2013-05-16 21:43:56