Мертвая блокировка MySQL InnoDB на SELECT с эксклюзивной блокировкой (ДЛЯ ОБНОВЛЕНИЯ)

Я делаю это, чтобы гарантировать запуск только одного экземпляра этого процесса (псевдокод 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 минуты, возникает ошибка «тайм-аут», а не тупик.

6
задан Quassnoi 25 March 2011 в 12:26
поделиться