Я делаю это, чтобы гарантировать запуск только одного экземпляра этого процесса (псевдокод 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 to COMMIT / ROLLBACK действительно миллисекунды - времени даже на таймаут не хватает. Как с этим кодом попасть в тупик? Я не использую другие таблицы в этой транзакции. Похоже, что тупик невозможен. Если 2 процесса запускаются одновременно, первый процесс, получивший блокировку в этой строке, продолжит работу, а другой будет ждать снятия блокировки. Если блокировка не снимается в течение 1 минуты, возникает ошибка «тайм-аут», а не тупик.