2

我有多个进程运行完全相同的脚本,问题是它们选择了相同的数据。我有一个标志“in_use”,被选中后设置为1,但是其他进程太快并且在脚本本身能够将所有数据更新为in_use = 1之前选择相同的数据。我该怎么办,也许在查询内部,确保永远不会选择相同的数据?以某种方式锁定它?

现在我为每个进程更新 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)同时运行:

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;";
4

1 回答 1

0

可能会考虑锁定表格

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

所以在 SELECT 你做之前

LOCK TABLE Domains WRITE;

在你这样做之后

UNLOCK TABLES;
于 2013-03-27T13:28:07.177 回答