2011-08-23 87 views
0

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

我查看了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' LIMIT 1
  2. 如果找到记录,然后更新MY_TABLE
  3. 否则,如果记录不发现,向my_table中插入新记录,然后继续其他查询

任何人都可以想到为什么这2个mysql进程似乎互相重叠的原因吗?任何帮助是极大的赞赏。谢谢。

+0

通过重叠,你的意思是在同一时间运行?你究竟遇到了什么实际问题? – HyderA

+0

如果数据是主键,请考虑使用INSERT ... ON DUPLICATE KEY UPDATE:http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html – HyderA

+0

两个进程ID指示两个与服务器的不同连接,指示两个单独的PHP脚本调用,提示两个单独的HTTP请求。 –

回答

0

尝试之前选择锁定表:

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表,并避免这种竞争情况。

+0

为什么锁定,如果有更优雅和更安全的解决方案?其中之一是在评论中张贴的重复密钥更新。 – Furicane