2015-08-14 76 views
0

我有一个表,其中每一行代表一个消费者可以使用的资源。该资源只能由一位消费者随时使用。消费者选择可用资源并随机挑选一个。为了确保消费者可以使用它选择的资源,我有以下SQL语句:UPDATE resource SET is_in_use=1 WHERE is_in_use=0 AND id=?MySQL UPDATE语句没有像预期的那样锁定行

如果受影响的行数= 1,我认为这意味着消费者会独占使用该资源。并非如此。我偶尔会遇到将多个消费者分配到单一资源的情况。

完整的PHP代码:

public function useResource() { 
    $mysqli = secureMysqli(); 
    if ($stmt = $mysqli->prepare("UPDATE resource SET is_in_use=1 WHERE is_in_use=0 AND id=?")) { 
     $stmt->bind_param('i', $this->id); 
     if($stmt->execute()) 
     { 
      if($mysqli->affected_rows == 1) { 
       return true; 
      } else { 
       return false; 
      } 
     } else { 
      return false; 
     } 
    } 
    return false; 
} 
+0

如果您将'is_in_use'字段从标志更改为某种类型的“consumer_id”,则可以在更新后重新检查该值以确认。 (另外,'resource.id'是唯一的或主键,对吗?) – Uueerdo

回答

0

这可能不是你要找的完整的答案,但有你的代码的一些改进。给出如下尝试:

public function useResource() { 
    $mysqli = secureMysqli(); 
    // add `` backticks around table and column names to prevent mysql reserved words error 
    if ($stmt = $mysqli->prepare("UPDATE `resource` SET `is_in_use` = 1 WHERE `is_in_use` = 0 AND `id` = ?")) { 
     $stmt->bind_param('i', $this->id); 
     $stmt->execute(); // No need to check if is executed. 

     if($mysqli->affected_rows == 1) { 
      return true; 
     } else { 
      return false; 
     } 
    } 
    return false; 
} 

如果你想检查是否正确执行您的查询添加:

if(!$stmt){ 
    echo $mysqli->error; 
} 

可以每$stmt号召下也是如此下添加准备,结合这一权利并执行语句

相关问题