【发布时间】:2010-12-28 21:41:46
【问题描述】:
有没有办法让 PHP 中的函数同步,以确保两个或多个 webuser 不能同时执行同一个函数?
【问题讨论】:
-
我认为您需要在此处提供更多信息。您尝试执行的函数不是线程安全的吗?
-
这个帖子有点老了,但我认为这是一个很好的答案:Stackoverflow
标签: php
有没有办法让 PHP 中的函数同步,以确保两个或多个 webuser 不能同时执行同一个函数?
【问题讨论】:
标签: php
我认为您可以通过使用sem_acquire 获取信号量(进入关键部分)和sem_release 来释放锁来实现相同的效果(如果可用)。
【讨论】:
您可以使用外部锁定 - 例如,通过flock 锁定文件。在某处创建一个文件并让脚本锁定它。您也可以使用semaphores,但这些仅适用于 Unix。
【讨论】:
我想不出您可能面临的任何问题。但是,我曾经必须编写一个 PHP 脚本来执行一些复杂的计算,并且我必须确保它不是由两个用户同时执行的。为此,我在脚本开始时创建了一个空文件,并在计算完成时将其删除。当然,脚本会在开始计算之前检查文件是否存在。
【讨论】:
请注意,本地文件锁定和信号量仅在您拥有一台 Web 服务器时才有效。如果您的脚本由多个负载平衡的服务器托管,您将不得不找到一些其他锁定机制,例如一台机器上的专用“锁定服务器”或某种通过 NFS 锁定的文件。
【讨论】:
更多关于你为什么需要锁的细节会很好。如果您遇到用户的数据库交互相互冲突的问题,您应该考虑在数据库代码中使用事务,以便数据库自动处理复杂的更改。
例如:我使用 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 的更改的大杂烩。
【讨论】:
过去,我在数据库中的记录上创建了简单的锁。如果您正在处理现有记录,则可以存储其类型、id 和锁定时间。确保 type 和 id 是数据库表(或缓存)的键。当您启动该过程时,您以不会擦除现有锁的方式获取锁。如果有过期的锁,就拿去吧。如果存在尚未过期的现有锁,则无法启动进程(队列或返回)。如果没有锁,或者存在已过期的锁,那么您就是黄金。你现在有了锁。完成后,释放锁。
您可以将这种系统绑定到数据库中已有的记录,为正在进行的工作创建新表,甚至使用外部缓存。
【讨论】: