我有多个进程运行完全相同的脚本,问题是它们选择了相同的数据。我有一个标志“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;";