PHP中的同步函数

时间:2010-12-28 21:41:47

标签: php

有没有办法让PHP中的函数同步,以确保两个或更多的webusers不能同时执行相同的功能?

6 个答案:

答案 0 :(得分:13)

我认为您可以通过使用sem_acquire获取信号量(输入标题部分)和sem_release来释放锁定来实现相同(如果可用)。

答案 1 :(得分:4)

您可以使用外部锁定 - 例如,通过flock锁定文件。在某处创建一个文件并让脚本锁定它。您也可以使用semaphores,但这些只是Unix。

答案 2 :(得分:1)

我想不出你可能遇到的任何问题。但是,我曾经不得不编写一个PHP脚本来进行一些复杂的计算,我必须确保它不是由两个用户同时执行的。为了实现这一点,我在脚本的开头创建了一个空文件,并在计算完成时将其删除。当然,脚本在开始计算之前检查文件是否存在。

答案 3 :(得分:1)

请注意,仅当您有一个Web服务器时,本地文件锁定和信号量才有效。如果您的脚本由多个负载平衡服务器托管,则必须找到一些其他锁定机制,例如一台计算机上的专用“锁定服务器”或通过NFS进行某种类型的文件锁定。

答案 4 :(得分:0)

过去,我在数据库中的记录上创建了简单的锁。如果您正在处理现有记录,则可以存储其类型,ID和锁定时间。确保type和id是数据库表(或缓存)的键。当您启动该过程时,您将以不会擦除现有锁的方式获取锁。如果有过期锁定,请将其取出。如果存在尚未过期的现有锁,则无法启动该进程(队列或返回)。如果没有锁定,或者存在过期的锁定,那么你就是金色的。你现在有了锁。完成后,释放锁定。

您可以将此类系统绑定到数据库中已有的记录,为正在进行的工作创建新表,甚至使用外部缓存。

答案 5 :(得分:0)

关于你需要锁的原因的更多细节会很好。如果您遇到用户数据库交互相互冲突的问题,您应该考虑在数据库代码中使用事务,以便数据库以原子方式处理复杂的更改。

作为一个例子:我使用Symfony和Doctrine ORM,所以我的提交代码通常看起来像这样:

$conn = Doctrine_Manager::connection();
$conn->beginTransaction();
try {
// .. database code ..
    $conn->commit();
} catch(Doctrine_Exception $ex) {
    $conn->rollback();
    // additional exception handling
}

现在,如果他们碰巧同时修改同一条记录,这将不会让用户互相破坏;但是,它将确保数据库保持一致 - 也就是说,用户A的更改生效或用户B的更改生效,但用户A和用户B的变化根据数据库的情绪从未改变。