【问题标题】:MySQL Queries overlapping each otherMySQL 查询相互重叠
【发布时间】:2011-08-23 17:15:56
【问题描述】:

我遇到了 MySQL 查询问题,有几个查询似乎相互重叠。基本上,我有一些使用带有 PDO 的 MySQL 的 PHP 代码(通过 REST API 调用),如果它不存在,则将值插入到表中。如果存在,则改为更新记录。非常简单的东西,它似乎在 99% 的时间里都在工作。但在某些情况下,同一条记录会被插入两次(而不是第二次更新)。

我查看了 MySQL 日志,发现在极少数情况下脚本会以某种方式同时运行两次(导致查询重叠)。请注意进程 ID 95587 和 95588 似乎是重叠的。

95587 Connect     @localhost on ****
95588 Connect     @localhost on ****
95587 Query       SET NAMES utf8
95588 Query       SET NAMES utf8
95588 Query       SELECT * FROM `my_table` WHERE `data` = '89158268' LIMIT 1
95587 Query       SELECT * FROM `my_table` WHERE `data` = '89158268' LIMIT 1
95588 Query       INSERT INTO `my_table` (`data`, `date_created`, `date_updated`) VALUES ('89158268', '2011-08-21 17:11:10 ', '2011-08-21 17:11:10 ')
95587 Query       INSERT INTO `my_table` (`data`, `date_created`, `date_updated`) VALUES ('89158268', '2011-08-21 17:11:10 ', '2011-08-21 17:11:10 ')
95588 Quit
95587 Query       SELECT * FROM `another_table`
95587 ... more queries

这是代码的顺序:

  1. SELECT * FROM my_table WHERE data = '89158268' 限制 1
  2. 如果找到记录,则更新 my_table
  3. 否则,如果找不到记录,则将新记录插入 my_table,然后继续其他查询

谁能想到这 2 个 mysql 进程似乎相互重叠的原因?任何帮助是极大的赞赏。谢谢。

【问题讨论】:

  • 重叠是指同时运行吗?您遇到的实际问题到底是什么?
  • 如果数据是主键,考虑使用 INSERT ... ON DUPLICATE KEY UPDATE:dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
  • 两个进程ID表示两个不同的服务器连接,表示两个单独的PHP脚本调用,表示两个单独的HTTP请求。
  • 这意味着有 2 个连接正在建立。似乎问题不在于为什么有 2 个进程,您的问题是解决问题的错误方法。使用 UNIQUE 约束和 ON DUPLICATE KEY UPDATE 可以解决重复记录的问题。处理完重复后,您可以继续研究为什么要建立 2 个连接而不是 1 个。由于您提供的信息不充分,因此很难判断发生了什么。

标签: php mysql


【解决方案1】:

尝试在选择之前锁定表格:

LOCK TABLE my_table WRITE;
SELECT * FROM `my_table` WHERE `data` = '89158268' LIMIT 1;
INSERT INTO `my_table` (`data`, `date_created`, `date_updated`);
UNLOCK TABLES;

这将避免任何其他 MySQL 会话使用 my_table 表,并避免这种竞争条件。

【讨论】:

  • 如果有更优雅、更安全的解决方案,为什么还要锁定?其中之一是在 cmets 中发布的重复密钥更新。
猜你喜欢
  • 2020-12-08
  • 1970-01-01
  • 1970-01-01
  • 2013-04-02
  • 2019-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多