2013-03-27 51 views
2

我有多個進程運行完全相同的腳本,問題是他們正在選擇相同的數據。我有一個標誌「in_use」,它被選中後被設置爲1,但其他進程太快並且在腳本本身已經能夠將所有數據更新爲in_use = 1之前選擇相同的數據。我怎麼能,也許在查詢中,確保從未選擇相同的數據?以某種方式鎖定它?MySQL多個進程選擇相同的數據

現在我爲每個進程更新in_use,但它不夠快或不夠安全。

DELIMITER // 

DROP PROCEDURE IF EXISTS `getDomainsForWhois`; 

CREATE PROCEDURE `getDomainsForWhois`(
    IN in_tld VARCHAR(10), 
    IN in_max_limit INT 
) 

BEGIN 
    SELECT 
     d.domainID, 
     CONCAT(SUBSTRING_INDEX(REPLACE(d.domainName, LOWER(d.tld), ''), '.' , -1), LOWER(d.tld)) as domainName, 
     d.tld 
    FROM 
     Domains d 
    WHERE (
     d.parentDomainID IS NULL 
    AND 
     d.tld = in_tld 
    AND 
     d.dateFetched <= DATE_SUB(CURRENT_TIMESTAMP(),INTERVAL 1 DAY) 
    AND 
     d.in_use = 0 
    ) 
    GROUP BY 
     domainName 
    ORDER BY 
     d.dateFetched ASC 
    LIMIT 
     0,in_max_limit 
    FOR 
     UPDATE; 
END// 

這基本上是我如何運行腳本。該腳本從多個進程(的cron)simaltaneously運行:

domains=`mysql -u USER -pPASSWORD DBNAME --skip-column-names -e "LOCK TABLE Domains WRITE; CALL getDomainsForWhois('.$1', $2)"`; 
while read domainID domainName domainTld 
do 
     mysql -u USER -pPASSWORD DBNAME -e "UPDATE Domains SET in_use = 1 WHERE domainID = $domainID"; 
done << EOF 
$domains 
EOF 

mysql -u USER -pPASSWORD DBNAME -e "UNLOCK TABLES;"; 
+0

你可以只使用select查詢嗎? '更新tbl設置MyLock = UniqueIDForPRocess然後從tbl中選擇*其中MyLock = UniqueIDForProcess – 2013-03-27 14:08:00

回答

0

它很可能是可能尋找到只鎖定表

http://dev.mysql.com/doc/refman/5.0/en/lock-tables.html

所以選擇之前,你做

LOCK TABLE Domains WRITE; 

然後你做

UNLOCK TABLES; 
+0

這會導致所有其他進程失敗,還是會在解鎖後立即獲得數據? – user2215771 2013-03-27 13:33:03

+0

任何其他請求都會等到鎖被釋放。他們然後也可能鎖定桌子。實際上,雖然這會使多個進程幾乎沒有用處,除非進程使用它們檢索的數據進行大量處理,因爲每個進程都將在那裏等待鎖釋放。另一種方法是在腳本中做一些事情,調用程序來精確地選擇他們選擇的內容,而不是依賴於此。 – 2013-03-27 13:34:49

+0

當我使用「SELECT d。* FROM Domains d」時,鎖定似乎不起作用,只有在不給表提供別名時(在本例中爲'd')。我該如何解決這個問題? – user2215771 2013-03-27 13:46:13

相關問題