У меня есть таблица базы данных, где мне нужно вывести строку, проверить ввод пользователя для соответствия, а затем обновить строку, чтобы определить пользователя, который сделал совпадение. Если возникает условие гонки, мне нужно убедиться, что обновление первого пользователя не перезаписано другим пользователем.PHP, mysqli и блокировки таблиц?
Для достижения этой цели я намерен:
1. Чтение строк таблицы
2. Замка снова
3. Прочитайте ряда и сравните исходную строку
4. Если строки совпадают обновления, в противном случае ничего не делать (другой пользователя уже обновил строку)
Основываясь на информации, которую я нашел в Google, я ожидал, что оператор таблицы блокировки будет заблокирован до тех пор, пока не будет получен замок. Я создал небольшой тестовый скрипт в PHP, который задержится на 10 секунд, чтобы позволить мне вручную создать условие гонки.
// attempt to increment the victor number
$aData["round_id"] = $DATABASE["round_id"];
// routine to execute a SELECT on database (ommited for brevity)
$aRound = $oRound->getInfo($aData);
echo "Initial Round Data:";
print_r($aRound);
echo "Locking...";
echo $oRound->lock();
echo "Stalling to allow for conflict...";
sleep(10);
echo "Awake...";
$aLockedRound = $oRound->getInfo($aData);
if($aRound["victor_nation"] == $aLockedRound["victor_nation"]){
$aData["victor_nation"] = $aRound["victor_nation"] + 1;
$oRound->update($aData);
echo "Incremented Victor Nation";
}
где режим блокировки определяется как
function lock(){
global $oDatabase;
$iReturn = 0;
// lock the table
$iReturn = $oDatabase->m_oConnection->query("LOCK TABLES round WRITE");
return $iReturn;
}
Выше $oDatabase->m_oConnection
является MySQLi соединение, которое я использую, чтобы выполнить подготовленные заявления по базе данных.
Когда я запускаю свой тестовый сценарий, я запускаю первого пользователя и жду, когда «Столбец разрешит конфликт ...», а затем запустите второй скрипт. Во втором скрипте я ожидал, что он заблокируется при «Блокировке ...», однако второй скрипт также продолжает «Стоять, чтобы разрешить конфликт ...».
Поскольку состояние LOCK не блокирует и не возвращает какой-либо индикатор получения блокировки (возвращаемое значение равно эхо и пустое), мне непонятно, что я фактически приобретаю блокировку. Даже если я, я не уверен, как действовать дальше.
Любые указатели?
Innodb или MyIsam стол? –
Таблица MyIsam –