php mysql atomic 'Выбрать и Удалить' на Таблице

0

У меня есть сценарий такой ситуации, когда каждый пользователь может отправить запрос, который добавляется в очередь, а другие могут принимать эти запросы по порядку этой очереди, но каждый запрос должен быть принят только одним пользователем. но если я реализую его с двумя запросами, один для выбора другого для удаления

что-то вроде этого

<?php
$sql = "SELECT id,CreationDate FROM 'RandomQueue' order by CreationDate limit 1 ;";
$result = $conn->query($sql);

if ($result->num_rows == 1) {
    $row = $result->fetch_assoc();

    echo "this request is accepted".$row['id'];

    $sqlDel = "DELETE FROM 'RandomQueue' WHERE id = {$row['id']}";
    $conn->query($sql);
}
?>

это не сработает, потому что может возникнуть много проблем, как два пользователя, принимающих один запрос и т.д. (проблема мьютекса), можно ли это сделать одним запросом sql (чтобы сделать его атомарным)? и если нет, то любое предложение о том, как реализовать эту логику, было бы неплохо, спасибо большое;

  • 1
    Если ваша таблица имеет тип InnoDB и вы используете PDO, вы ищете PDO beginTransaction и PDO commit
Теги:

1 ответ

0
Лучший ответ

Atomicity является одним из свойств транзакции базы данных (ACID), поэтому вам нужно убедиться, что транзакция базы данных поддерживает транзакцию.

В MySQL MyISAM не поддерживает транзакцию, и вы должны использовать InnoDB.

Если вы используете InnoDB, есть два способа начать транзакцию базы данных для MySQL в PHP

/* Begin a transaction, turning off autocommit */
$dbh->beginTransaction();

// your business logic goes here

$dbh->commit();

или же

$mysqli->begin_transaction(MYSQLI_TRANS_START_READ_ONLY);
// your business logic goes here
$mysqli->commit();
  • 0
    Спасибо Джейкобу и Дейву за ваше предложение, но, как я понял, этот подход делает его атомарным, как если бы один из двух запросов не удался, он отменял бы все, но моя проблема не только в этом.
  • 0
    возможно, что в то же время один пользователь получит результат выбора (до его удаления), другой пользователь может получить тот же результат, потому что он все еще не удален, и два пользователя получат одну и ту же строку, что я хочу предотвратить
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню