MySQL InnoDB dead lock on SELECT with exclusive lock (FOR UPDATE)

后端 未结 3 1103
野的像风
野的像风 2020-12-19 09:48

I do this to ensure only once instance of this process is running (pseudo code php/mysql innodb):

START TRANSACTION
$rpid = SELECT `value` FROM locks WHERE n         


        
3条回答
  •  天涯浪人
    2020-12-19 10:26

    Just figured it out thanks to Quassnoi's answer...

    I can do:

    $myPid = posix_getpid();
    $gotIt = false;
    while(true){
      START TRANSACTION;
      $pid = SELECT ... FOR UPDATE; // read pid and get lock on it
      if(mysql_num_rows($result) == 0){
        ROLLBACK;// release lock to avoid deadlock
        INSERT IGNORE INTO locks VALUES('lockname', $myPid);
      }else{
        //pid existed, no insert is needed
        break;
      }
    }
    
    if($pid != $myPid){ //we did not insert that
      if($pid>0 && isRunning($pid)){
        ROLLBACK;
        echo 'another process is running';
        exit;
      }{
        // no other process is running - write $myPid in db
        UPDATE locks SET value = $myPid WHERE name = 'lockname'; // update is safe
        COMMIT;
      }
    }else{
      ROLLBACK; // release lock
    }
    

提交回复
热议问题