2011-08-23 70 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