题 PHP中的同步函数


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


13
2017-12-28 21:41


起源


我想你需要在这里提供更多信息。您尝试执行的功能是否不是线程安全的? - sberry
这个帖子有点旧,但我认为这是一个非常好的答案: 堆栈溢出 - Nicsoft


答案:


我认为您可以通过使用实现相同(如果可用) sem_acquire 获得信号量(进入暴击部分)和 sem_release 释放锁。


13
2017-12-28 21:51



sem_acquire和sem_release默认不可用,它们在Windows上不可用 php.net/manual/en/intro.sem.php - Lukasz
@Lukas我想这是真的。 - Alfred


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


4
2017-12-28 21:51



我喜欢这个答案。 这里 是“羊群”方法的一个例子。 - mevdschee


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


1
2017-12-28 21:45



但是,数据库可能更快。
我总是对的,卢卡斯。 :)
考虑一下:prcess 1 cecks我文件存在但它不存在。然后过程的次数接近结束,它是过程二次转动它检查是否存在,并且因为pocess二尚未创建它。两个过程同时运行!您的解决方案可以降低风险,但并不能消除风险。你可以像Alfred建议的那样使用sem_aquire。 - Oliver A.
@Oliver A。:请记住,我很久以前就描述了我使用的解决方案。我没有说这是最好的一个。 - Lukasz
巴兰。我从不打算攻击/侮辱你。我只是想指出,这并不像听起来那样节省。 - Oliver A.


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


1
2017-12-28 22:05





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

举个例子:我使用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的变化根据数据库的情绪从不改变。


0
2017-12-29 04:33





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

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


0
2017-12-28 22:05