这可能看起来像一个非常简单的问题,我可能知道我是否对计算机程序等有更深入的了解,但无论如何......
如果有两个人从我的服务器请求同一页面,那么PHP页面是为第一个人处理一次,然后是第二次处理第二个人,或者这些页面可能同时并排运行吗?
以此为例。我的PHP驱动的在线商店里有一个库存物品。用户将此添加到他们的购物车。 Php脚本1)检查它是否有库存,是的,它的库存,所以它2)为他预留。
如果在检查其库存和保留之间,是否为其他人加载了相同的PHP页面,并且在用户A检查了它是否有库存之后,用户B也是如此,在用户A有机会之前保留它,所以他们最终保留它!
抱歉,如果这看起来很傻,似乎无法找到答案,这是什么?
答案 0 :(得分:7)
恭喜,您已确定race condition! : - )
PHP页面是并行运行还是依次运行取决于Web服务器。通常,Web服务器会分配多个线程来同时处理多个传入请求。因此,如果两个或多个用户同时请求同一页面,则可能确实会发生同一脚本的多个实例并行运行。由于时间和调度的差异,当每个页面完全执行哪个动作时,它是不可预测的。
因此,对于您描述的情况,以原子方式编写动作非常重要,这意味着它们要么完整地完成,要么根本不完整。在您的情况下,您可以使用锁,事务,巧妙形成的UPDATE
语句,UNIQUE
索引或许多其他技术,以避免两个用户保留相同的东西。
答案 1 :(得分:2)
是的,一般情况下,没有详细说明: PHP脚本会同时针对每个请求执行。
为了确保不会出现您提到的问题,您可能应该实现名为“ transactions ”的数据库管理系统的功能。这样,如果您在数据库层上执行某些操作,最后您会发现预订不会发生,事务中所做的所有操作都将被回滚。
除了之外,你应该设计你的应用程序,记住你提到的问题可能会发生。因此,您应该设计您的数据库&以一种方式申请,1)尽可能缩短“检查”和“保留”之间的时间,2)如果你不能预约就停止行动,最后 - 在紧急情况下 - 3)确定哪个预订来了首先应该撤销。
属于“您的应用程序设计”类别的另一个想法可能是我们称之为“ 临时预订 ”。这意味着如果您即将预订,您可以暂时(例如,持续几秒钟)锁定您的预订。之后,您可以检查您是否真的可以进行预订,并将其转为永久预订或只是撤销它。我相信一些系统在客户开始预订他/她的位置之后立即进行更长时间的临时预订。然后,如果流程成功,则预订将更改为永久性,但如果某个特定时间段内没有成功,则可以简单地撤销预订,允许其他客户开始此过程。
答案 2 :(得分:-1)
是和否。 PHP可以在同时进程中运行,具体取决于服务器设置,但在小规模上,您只能拥有一个数据库。数据库查询是按顺序处理的,因此您永远不会遇到这种冲突。 (只要您在为某人预订之前检查某件商品是否有货就可以了。)More information
当然,用户A + B可能都看到它有库存,而A可能会在B之前请求它。但是您的代码可以意识到它现在缺货并向用户B显示错误。
(您遇到了多个数据库服务器的问题。如果您在多个服务器上存储了相同的数据,那么在完全复制数据之前会有滞后时间。但是您不会遇到这个问题。我们说的是前1000名这里的网站。)
答案 3 :(得分:-1)