Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL在高负载、竞争条件下?_Mysql - Fatal编程技术网

MySQL在高负载、竞争条件下?

MySQL在高负载、竞争条件下?,mysql,Mysql,在我参与的一个应用程序中,我遇到的似乎是竞争条件的影响。情况如下,通常,负责一些重应用程序逻辑的页面采用以下格式: 从test中选择,并确定是否已经有行与子句匹配。 如果匹配行已经存在,我们在这里终止,否则继续应用程序逻辑 在test表中插入与初始选择匹配的值 通常情况下,这可以很好地工作,并将操作限制为一次执行。然而,在高负载和用户滥用的情况下,许多请求被故意同时发送,MySQL允许许多应用程序逻辑实例运行,从而绕过select子句的限制 它实际上似乎运行着类似于: 从测试中选择 从测试中选择

在我参与的一个应用程序中,我遇到的似乎是竞争条件的影响。情况如下,通常,负责一些重应用程序逻辑的页面采用以下格式:

test
中选择,并确定是否已经有行与子句匹配。
如果匹配行已经存在,我们在这里终止,否则继续应用程序逻辑
test
表中插入与初始选择匹配的值

通常情况下,这可以很好地工作,并将操作限制为一次执行。然而,在高负载和用户滥用的情况下,许多请求被故意同时发送,MySQL允许许多应用程序逻辑实例运行,从而绕过select子句的限制

它实际上似乎运行着类似于:
从测试中选择
从测试中选择
从测试中选择
(全部通过检查)
插入测试
插入测试
插入测试

我相信这样做是为了提高效率,但在我的应用程序中,它会产生严重的影响。我尝试使用Get_Lock()和Release_Lock(),但这在高负载下似乎不够,因为竞争条件似乎仍然存在。事务也是不可能的,因为应用程序逻辑非常繁重,并且涉及的所有表都不支持事务


对于熟悉这种行为的人来说,是否可以关闭这种类型的处理,以便MySQL始终按照接收查询的顺序处理查询?有没有其他方法使这种查询原子化?对此问题的任何帮助都将不胜感激,我找不到关于这种行为的详细记录。

就我个人而言,我会以另一种方式进行检查

尝试插入该行。如果它失败了,那么那里已经发生了争吵


通过这种方式,您可以在单个查询中检查或复制并插入新行,从而消除竞争的可能性。

这里的问题是,正如您所猜测的,您有一个竞争条件

选择
插入
必须是一个原子单位

您这样做的方式是通过事务。您无法安全地进行
选择
,返回PHP,并假设在进行
插入
时,
选择
的结果将反映数据库状态

如果如您所说,设计良好的事务(正确的解决方案)是不可能的——我仍然强烈推荐它们——那么您将不得不以原子方式进行最后的
插入
,检查其假设是否仍然正确(例如通过
插入(如果不存在)
、存储过程,或捕获应用程序中的
插入
错误)。如果不存在,它将中止返回到PHP代码,而PHP代码必须重新启动逻辑


顺便说一句,MySQL可能是按照接收请求的顺序执行请求的。通过多个同时连接可以接收
选择A
选择B
插入A
插入B
。因此,唯一的“解决方案”一次只允许一个连接-这将扼杀您的可伸缩性。

谢谢,这似乎是一个可能的解决方案。如何进行原子化检查假设是否仍然正确。如果通过逻辑顶部的简单选择,新数据是否仍不可能反映在选项卡中le?@majicbunnie您将第二个
插入
存储过程,该存储过程执行
开始事务;选择;[检查];INSERT;END TRANSACTION;
。谢谢,我认为这对我来说是可行的,尽管我可能需要更改某些存储引擎类型以支持事务。据我所知,它们都必须具有事务功能,这样的解决方案才能正常工作。