У меня есть система, которая обрабатывает много запросов в секунду. Я кодирую свою систему с mysql
а также PHP
,
Моя проблема заключается в том, что транзакция mysqli все еще фиксирует транзакцию, даже если запись удалена другим пользователем в то же время, все мои таблицы используют InnoDB
,
Вот как я кодирую свою транзакцию с помощью mysqli:
mysqli_autocommit($dbc,FALSE);
$all_query_ok=true;
$q="INSERT INTO Transaction() VALUES()";
mysqli_query ($dbc,$q)?null:$all_query_ok=false;
$q="INSERT INTO Statement() VALUES()";
mysqli_query ($dbc,$q)?null:$all_query_ok=false;
if($all_query_ok==true){
//all success
mysqli_commit($dbc);
}else{
//one of it failed , rollback everything.
mysqli_rollback($dbc);
}
Ниже приведен запрос, выполняемый в то же время в другом сценарии другим пользователем, а затем в итоге запутывается ожидаемое поведение системы,
$q="DELETE FROM Transaction...";
mysqli_query ($dbc,$q)?null:$all_query_ok=false;
Пожалуйста, совет, я неправильно осуществил транзакцию? Я читал о блокировке на уровне строк и считаю, что innoDB
блокирует запись во время транзакции
Я не знаю, о каких транзакциях вы говорите, но с mysqli
Расширение Я использую следующие методы для работы с транзакциями:
Тогда процесс выглядит так:
mysqli::begin_transaction
mysqli::commit
подтвердить изменения, сделанные по вашим запросам в шаге 2 ИЛИ ЖЕ при ошибке во время выполнения ваших запросов в шаге 2 используйте mysqli::rollback
отменить изменения, сделанные ими.Вы можете рассматривать транзакции как временный кеш для ваших запросов. Это похоже на кэширование вывода в PHP с ob_*
функции. Пока вы не сбросили кэшированные данные, на экране ничего не происходит. То же самое с транзакциями: пока вы ничего не зафиксировали (а автокоммит отключен), в базе данных ничего не происходит.
Я провел некоторые исследования по блокировке на уровне строк, которые могут заблокировать запись от удаления или обновления
ДЛЯ ОБНОВЛЕНИЯ
Сразу после начать транзакцию Я должен выбрать те записи, которые я хотел заблокировать, как показано ниже
SELECT * FROM Transaction WHERE id=1 FOR UPDATE
Так что запись будет заблокирована до transaction end
,
Этот метод не работает с таблицей типов MyISAM
Выглядит как типичный пример состояние гонки. Вы выполняете два параллельных сценария, изменяющих данные параллельно. Вероятно, ваш первый сценарий успешно вставляет записи и фиксирует транзакцию, а второй сценарий успешно удаляет записи впоследствии. Я не уверен, что вы подразумеваете под «запросом, выполняемым в то же время в другом скрипте другим пользователем».
Вам придется сделать это следующим образом:
mysqli_autocommit($dbc,FALSE);
$dbc->begin_transaction();
$all_query_ok=true;
$q="INSERT INTO Transaction() VALUES()";
mysqli_query ($dbc,$q)?null:$all_query_ok=false;
$q="INSERT INTO Statement() VALUES()";
mysqli_query ($dbc,$q)?null:$all_query_ok=false;
if($all_query_ok==true){
//all success
mysqli_commit($dbc);
}else{
//one of it failed , rollback everything.
mysqli_rollback($dbc);
}
Вы можете использовать объектно-ориентированный или процедурный стиль при вызове begin_transaction (я предпочитаю объектно-ориентированный).