W3docs

autocommit

Функция mysqli_autocommit() в PHP: управление режимом автофиксации транзакций MySQLi, синтаксис и примеры.

В этой статье рассматривается функция mysqli_autocommit() в PHP, которая включает или отключает режим автофиксации (autocommit) в MySQLi. Вы узнаете, что такое autocommit, познакомитесь с объектно-ориентированным и процедурным синтаксисом, а также научитесь использовать её совместно с mysqli_commit() и mysqli_rollback() для безопасных транзакций «всё или ничего».

Что такое autocommit

Транзакция — это группа SQL-операторов, которые должны либо все выполниться успешно, либо все потерпеть неудачу вместе. По умолчанию MySQLi работает в режиме автофиксации (autocommit): каждый отдельный оператор является собственной транзакцией и сразу сохраняется (фиксируется) в базе данных в момент выполнения. Отменить его после этого невозможно.

mysqli_autocommit() позволяет отключить это автоматическое поведение. После отключения autocommit ваши операторы удерживаются в ожидающей транзакции до тех пор, пока вы не решите, что с ними делать:

  • Вызовите mysqli_commit(), чтобы сделать все ожидающие изменения постоянными.
  • Вызовите mysqli_rollback(), чтобы отменить их, оставив базу данных нетронутой.

Именно это делает возможными обновления «всё или ничего» — например, перевод денег между двумя счетами, где и дебет, и кредит должны выполниться успешно, либо не выполниться вовсе.

Как использовать функцию mysqli_autocommit()

Использовать функцию mysqli_autocommit() очень просто. Нужно лишь вызвать функцию и передать действующее соединение MySQLi и boolean-значение, определяющее состояние autocommit.

Параметры:

  • connection (процедурный) / $mysqli (ООП): объект соединения MySQLi.
  • mode (bool): TRUE — включить autocommit, FALSE — отключить.

Возвращаемое значение: возвращает TRUE при успехе, FALSE при ошибке.

Примечание: MySQLi поддерживает как объектно-ориентированный, так и процедурный синтаксис. Метод ООП: $mysqli->autocommit($mode); процедурный эквивалент: mysqli_autocommit($mysqli, $mode). Оба делают одно и то же — выбирайте стиль, который уже используется в вашей кодовой базе. Подробнее о двух стилях см. в разделе PHP MySQLi overview.

Вот базовый пример с использованием объектно-ориентированного стиля:

Как использовать функцию mysqli_autocommit()

<?php
$mysqli = new mysqli("localhost", "username", "password", "database");
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: " . $mysqli->connect_error;
    exit();
}

$mysqli->autocommit(FALSE);

$mysqli->query("INSERT INTO users (name, email) VALUES ('John', '[email protected]')");
$mysqli->query("UPDATE users SET name='John Doe' WHERE id=1");

$mysqli->commit();

$mysqli->autocommit(TRUE);

$mysqli->close();
?>

В этом примере мы создаём новый объект MySQLi и отключаем autocommit, вызвав функцию autocommit() с аргументом FALSE. Затем выполняем два запроса: вставку и обновление данных в таблице users. Фиксируем транзакцию, вызвав функцию commit() объекта MySQLi.

Затем снова включаем autocommit, вызвав функцию autocommit() с аргументом TRUE. Наконец, закрываем соединение MySQLi методом close() объекта MySQLi.

Процедурный синтаксис

Та же логика, написанная в процедурном стиле, передаёт соединение первым аргументом каждой функции:

<?php
$link = mysqli_connect("localhost", "username", "password", "database");
if (mysqli_connect_errno()) {
    echo "Failed to connect to MySQL: " . mysqli_connect_error();
    exit();
}

// Turn off autocommit so the statements form one transaction
mysqli_autocommit($link, FALSE);

mysqli_query($link, "INSERT INTO users (name, email) VALUES ('John', '[email protected]')");
mysqli_query($link, "UPDATE users SET name='John Doe' WHERE id=1");

mysqli_commit($link);          // make both changes permanent

mysqli_autocommit($link, TRUE); // restore default behavior
mysqli_close($link);
?>

Откат при ошибке

Настоящая ценность отключения autocommit — это возможность отменить частично выполненную транзакцию при возникновении ошибки. Пример ниже оборачивает два связанных обновления в транзакцию и выполняет откат, если хотя бы один из запросов завершается неудачей, чтобы база данных никогда не оставалась в наполовину обновлённом состоянии:

<?php
$mysqli = new mysqli("localhost", "username", "password", "database");
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: " . $mysqli->connect_error;
    exit();
}

$mysqli->autocommit(FALSE); // begin a transaction

$ok = $mysqli->query("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
$ok = $ok && $mysqli->query("UPDATE accounts SET balance = balance + 100 WHERE id = 2");

if ($ok) {
    $mysqli->commit();
    echo "Transfer completed.";
} else {
    $mysqli->rollback(); // discard both updates
    echo "Transfer failed and was rolled back.";
}

$mysqli->autocommit(TRUE);
$mysqli->close();
?>

Поскольку autocommit отключён, ни один UPDATE не сохраняется до вызова commit(). Если второй запрос завершается неудачей, rollback() отменяет и первый, гарантируя, что деньги никогда не будут списаны без зачисления.

Расширенное использование

Функция mysqli_autocommit() работает на уровне соединения. При переключении autocommit с FALSE на TRUE MySQLi автоматически фиксирует все ожидающие транзакции. Это поведение удобно при управлении несколькими независимыми транзакциями последовательно в одном скрипте. Вот пример:

Расширенное использование PHP autocommit()

<?php
$mysqli = new mysqli("localhost", "username", "password", "database");
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: " . $mysqli->connect_error;
    exit();
}

// Start and commit the first transaction
$mysqli->autocommit(FALSE);
$mysqli->query("INSERT INTO users (name, email) VALUES ('John', '[email protected]')");
$mysqli->commit();

// Start and commit the second transaction
$mysqli->autocommit(FALSE);
$mysqli->query("UPDATE users SET name='John Doe' WHERE id=1");
$mysqli->commit();

// Re-enable autocommit for subsequent queries
$mysqli->autocommit(TRUE);

$mysqli->close();
?>

В этом примере мы отключаем autocommit и выполняем запрос INSERT. Затем явно фиксируем первую транзакцию. Далее снова отключаем autocommit, чтобы начать вторую транзакцию, выполняем запрос UPDATE и фиксируем её. Наконец, снова включаем autocommit и закрываем соединение MySQLi.

Заключение

Функция mysqli_autocommit() даёт вам контроль над тем, когда MySQLi сохраняет изменения. Отключите её с помощью FALSE, чтобы начать транзакцию, выполните операторы, а затем либо вызовите mysqli_commit(), чтобы сделать изменения постоянными, либо mysqli_rollback(), чтобы их отменить. Этот шаблон необходим всегда, когда несколько операторов должны выполниться или завершиться неудачей как единое целое. Всегда повторно включайте autocommit (или закрывайте соединение) после завершения работы, чтобы последующие запросы вели себя ожидаемо, а данные оставались согласованными.

Практика

Практика
Что делает режим autocommit в PHP?
Что делает режим autocommit в PHP?
Was this page helpful?