首页 > 解决方案 > 如何处理mysql中的并发访问?

问题描述

如果一个购物网站只有 1 种产品可用,而 2 人同时尝试购买,那么谁将获得该产品?服务器将如何优先考虑用户。“对亚马逊的闪购感到好奇,翻转卡丁车”。哪个算法?

标签: mysqlweb-servicesconcurrencydatabase-concurrency

解决方案


以下是幕后可能发生的事情,使用任何现代应用程序框架都很容易实现。

我假设您的情况是:

  • 两个登录到您系统的用户说他们是U1并且U2
  • 选择一个产品
  • 只有一种产品可用
  • 他们都点击了加入购物车/立即购买/结帐
  • 将为一位用户提供服务,并通知另一位用户该产品不再可用

假设T1T2是他们单击结帐按钮时的纳秒表示。T1T2彼此相等的机会非常低,但有可能。

在您的情况下,网络服务器将在两个不同的线程中为用户生成的请求提供服务,TH1并且TH2. 这是极不可能的,因为在任何给定时间您的系统中都存在数百名用户,但假设您有多个内核,并且由 CPU 的两个不同内核提供服务TH1并非不可能。TH2

因此,两者都TH1TH2尝试抓住您的产品。

现在您需要在PRODUCT:VERSIONCHECKED_OUT.

TH1和都TH2将同时启动它们自己的事务,比如TR1TR2,假设你有 InnoDB 作为你的数据库引擎。

TR1和都TR2将:

  • PRODUCT从数据库表中读取您的VERSIONCHECKED_OUT:{id: 1, version: 0, checked_out: 0, ...}并将其传输到服务器。
  • 在服务器中,TR1TR2都将增加VERSION之前读取的值并执行更新语句,说明UPDATE PRODUCT SET CHECKED_OUT = 1, VERSION = 1 WHERE ID = 1 AND VERSION = 0
  • DB将锁定行,执行UPDATE并以顺序方式返回修改行的编号,因为UPDATE应该在单个线程中执行。注意这里,这个线程是 DB 自己的线程,而不是TR1and TR2
  • 在这里,如果我假设之前,即TR1由DB 的线程提供服务,那么后面的业务逻辑将得到更新的行数等于 1,而更新的行数将得到 0。TH1TR2TH2UPDATETR1TR2
  • 这反过来意味着U1可以检查产品,同时U2会收到一条很好的道歉信息。

推荐阅读