如果有两个人同时向数据库发送相同的查询,而另一个查询返回不同的内容,会发生什么?
我有一个商店,剩下一件商品。两个或更多人购买该项目,并且查询在MySQL服务器上完全同时到达。我的猜测是它会排队,但如果是这样,MySQL如何选择第一个执行的,我可以对此产生影响吗?
答案 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,那么默认会发生这样的事情:
items
中id
为100 quantity
从1更改为0并解锁行items
中id
为100 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。