如果购物网站上只有1种产品可用,而2个人尝试同时购买,那么谁会得到该产品?服务器将如何确定用户的优先级。“对亚马逊上的快速销售感到好奇”。哪种算法?
最佳答案
以下是幕后可能发生的事情,使用任何现代应用程序框架都非常容易实现。
我假设您的情况是:
登录到系统中的两个用户说他们是U1
和U2
选择一个产品
仅有一种产品
他们都单击了添加到购物车/立即购买/结帐
将为一个用户提供服务,并且将通知另一用户该产品不再可用
假设T1
和T2
是单击结帐按钮时的时间的纳秒表示。 T1
和T2
彼此相等的机会很小,但是有可能。
在您的情况下,Web服务器将在两个不同的线程TH1
和TH2
中满足用户生成的两个请求。这是极不可能的,因为在任何给定时间,系统中都会有数百个用户,但是TH1
和TH2
由CPU的两个不同内核提供服务并不是不可能的,前提是您拥有多个内核。
因此,TH1
和TH2
都将尝试保留您的产品。
现在,您需要为PRODUCT
提供/引入两个属性(如MySQL列):VERSION
和CHECKED_OUT
。
假设您使用InnoDB作为数据库引擎,TH1
和TH2
将同时启动自己的事务,例如TR1
和TR2
。TR1
和TR2
都将:
从数据库表中读取PRODUCT
以及VERSION
和CHECKED_OUT
:{id: 1, version: 0, checked_out: 0, ...}
并将其传输到服务器。
在服务器中,TR1
和TR2
都将增加先前读取的VERSION
值,并执行一条Update语句,指出UPDATE PRODUCT SET CHECKED_OUT = 1, VERSION = 1 WHERE ID = 1 AND VERSION = 0
因为UPDATE
应该在单个线程中执行,所以DB将锁定该行,执行UPDATE
并按顺序返回修改后的行号。请注意,此线程是数据库自己的线程,而不是TR1
和TR2
。
在这里,如果我假设TR1
(即TH1
在TR2
之前,即TH2
由DB的UPDATE
线程提供),则TR1
之后的业务逻辑将得到更新的行数相等设为1,而TR2
的值为0。
这反过来意味着U1
可以检出产品,而U2
会收到一条很好的道歉消息通知。