MySQL队列查询吗?

时间:2013-04-20 10:00:31

标签: php mysql sql database

如果有两个人同时向数据库发送相同的查询,而另一个查询返回不同的内容,会发生什么?

我有一个商店,剩下一件商品。两个或更多人购买该项目,并且查询在MySQL服务器上完全同时到达。我的猜测是它会排队,但如果是这样,MySQL如何选择第一个执行的,我可以对此产生影响吗?

5 个答案:

答案 0 :(得分:6)

  

同时发送相同的查询

查询并不总是并行运行

这取决于数据库引擎。使用MyISAM,几乎每个查询都获得一个表级锁,这意味着查询作为队列顺序运行。对于大多数其他引擎,它们可以并行运行。

echo_me说nothing happens at the exact same time and a CPU does not do everything at once

这不完全正确。 DBMS可能可以在具有多个cpu且具有多个网络接口的计算机上运行。 2个查询可以同时到达,但不是不可能,这是非常不可能的,因此有一个互斥体可以确保配对/执行转换只作为单个线程运行(执行 - 不一定是相同的轻量级过程)。

有两种解决concurent DML的方法 - 使用事务(每个用户有效地获取数据库的克隆)以及查询完成后DBMS尝试协调任何更改 - 如果协调失败,则DBMS滚动返回其中一个查询并将其报告为失败。另一种方法是使用行级锁定 - DBMS识别将由查询更新的行并将它们标记为保留用于更新(其他用户可以读取每行的原始版本,但任何更新数据的尝试都将是阻止,直到该行再次可用。)

你的问题是你有两个mysql客户端,每个客户端都检索到剩下一个库存的事实。由于(自提到PHP以来)库存水平可能已在不同的DBMS会话中检索而不是后续库存调整这一事实使您更加复杂 - 您不能拥有超过HTTP请求的事务。因此,您需要在单个事务中重新验证在DBMS外部维护的任何事实。

乐观锁定可以创建一个伪事务控制机制 - 您使用时间戳和用户标识符(使用PHP PHP会话ID是一个不错的选择)标记您要修改的记录 - 如果您来修改它,其他东西改变了它,然后你的代码知道它先前检索的数据是无效的。然而,这可能导致其他并发症。

答案 1 :(得分:4)

一旦用户请求它们就会被执行,因此如果有10个用户在同一时间请求查询,那么将在同一时间执行10个查询。

在同一时间没有任何事情发生,并且CPU不会立即执行所有操作。它一次做一件事(每个核心和/或线程)。如果10个用户正在访问运行查询的页面,他们将按特定顺序“命中”服务器并按该顺序处理(尽管该顺序可能以毫秒为单位)。但是,如果页面上有多个查询,则无法确定在另一个用户页面上的查询开始之前,一个用户页面上的所有查询都将完成。这可能会导致并发问题。

编辑:

运行SHOW PROCESSLIST以查找要杀死的连接的ID

SHOW PROCESSLIST会为您提供所有当前正在运行的查询的列表。

来自here

MySQL可以很好地运行快速CPU,因为每个查询都在一个线程中运行,不能在CPU之间并行化。

答案 2 :(得分:3)

考虑类似于以下的查询:

UPDATE items SET quantity = quantity - 1 WHERE id = 100

然而,MySQL服务器并行运行的查询很多,如果运行2个这样的查询并且id 100的行有quantity 1,那么默认会发生这样的事情:

  1. 第一个查询会锁定itemsid为100
  2. 的行
  3. 第二个查询尝试执行相同操作,但该行已锁定,因此等待
  4. 第一个查询将quantity从1更改为0并解锁行
  5. 第二个查询再次尝试,现在看到该行已解锁
  6. 第二个查询会锁定itemsid为100
  7. 的行
  8. 第二个查询将quantity从0更改为-1并解锁行

答案 3 :(得分:2)

这本质上是一个并发问题。有一些方法可以通过使用事务来确保MySQL的并发性。这意味着在您的电子商店中,您可以确保您所描述的竞争条件不会成为问题。请参阅下面有关MySQL中的事务的链接。

http://dev.mysql.com/doc/refman/5.0/en/sql-syntax-transactions.html

http://zetcode.com/databases/mysqltutorial/transactions/

根据您的隔离级别,将从两个并发查询中返回不同的结果。

答案 4 :(得分:0)

MySQL中的查询是并行处理的。你可以read more about the implementation here