2015-08-14 2 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 вызова, так и при подготовке, связывает и операторы выполнения