Запись удалена во время транзакции

У меня есть система, которая обрабатывает много запросов в секунду. Я кодирую свою систему с 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 блокирует запись во время транзакции

1

Решение

Я не знаю, о каких транзакциях вы говорите, но с mysqli Расширение Я использую следующие методы для работы с транзакциями:

Тогда процесс выглядит так:

  1. Начало новой транзакции с mysqli::begin_transaction
  2. Выполните ваши запросы SQL
  3. По успешному использованию mysqli::commit подтвердить изменения, сделанные по вашим запросам в шаге 2 ИЛИ ЖЕ при ошибке во время выполнения ваших запросов в шаге 2 используйте mysqli::rollback отменить изменения, сделанные ими.

Вы можете рассматривать транзакции как временный кеш для ваших запросов. Это похоже на кэширование вывода в PHP с ob_* функции. Пока вы не сбросили кэшированные данные, на экране ничего не происходит. То же самое с транзакциями: пока вы ничего не зафиксировали (а автокоммит отключен), в базе данных ничего не происходит.

2

Другие решения

Я провел некоторые исследования по блокировке на уровне строк, которые могут заблокировать запись от удаления или обновления

ДЛЯ ОБНОВЛЕНИЯ

Официальная документация

Сразу после начать транзакцию Я должен выбрать те записи, которые я хотел заблокировать, как показано ниже

SELECT * FROM Transaction WHERE id=1 FOR UPDATE

Так что запись будет заблокирована до transaction end,

Этот метод не работает с таблицей типов MyISAM

1

Выглядит как типичный пример состояние гонки. Вы выполняете два параллельных сценария, изменяющих данные параллельно. Вероятно, ваш первый сценарий успешно вставляет записи и фиксирует транзакцию, а второй сценарий успешно удаляет записи впоследствии. Я не уверен, что вы подразумеваете под «запросом, выполняемым в то же время в другом скрипте другим пользователем».

0

Вам придется сделать это следующим образом:

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 (я предпочитаю объектно-ориентированный).

0
По вопросам рекламы [email protected]