【发布时间】:2011-03-25 12:24:39
【问题描述】:
我这样做是为了确保该进程的实例只运行一次(伪代码 php/mysql innodb):
START TRANSACTION
$rpid = SELECT `value` FROM locks WHERE name = "lock_name" FOR UPDATE
$pid = posix_getpid();
if($rpid > 0){
$isRunning = posix_kill($rpid, 0);
if(!$isRunning){ // isRunning
INSERT INTO locks values('lock_name', $pid) ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)
}else{
ROLLBACK
echo "Allready running...\n";
exit();
}
}else{ // if rpid == 0 -
INSERT INTO locks values('lock_name', $pid) ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)
}
COMMIT
...............
//free the pid
INSERT INTO locks values('lock_name', 0) ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)
表锁包含以下字段:
id - primary, autoinc
name - varchar(64) unique key
description - text
value - text
我相信从 START TRANSACTIN 到 COMMIT/ROLLBACK 的时间实际上是毫秒 - 甚至没有足够的时间来获得超时。这段代码怎么可能陷入僵局?我不使用此事务中的其他表。看起来死锁是不可能的。如果 2 个进程同时启动,第一个获得该行锁的进程将继续进行,另一个将等待锁被释放。如果锁没有在 1 分钟内释放,则错误是“超时”,而不是死锁。
【问题讨论】:
标签: mysql transactions innodb deadlock