Я использую версию MariaDB 10.3.13. В последний раз, когда я проверял, флаг autocommit включен.

MariaDB> SHOW VARIABLES WHERE Variable_name='autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+

Как я читал в документе, когда автокоммит включен, вы не можете откатить транзакцию, как указано здесь

По умолчанию MySQL работает с включенным режимом автоматической фиксации. Это означает, что как только вы выполняете инструкцию, которая обновляет (модифицирует) таблицу, MySQL сохраняет обновление на диске, чтобы сделать его постоянным. Изменение не может быть отменено.

Поэтому я пишу небольшой скрипт для тестирования. Сначала я запускаю транзакцию и обновляю некоторые данные:

BEGIN;
UPDATE foo SET year = 2019  WHERE id = 1;
Query OK, 1 row affected (0.000 sec)
Rows matched: 1  Changed: 1  Warnings: 0

Похоже, что я сделал. Тогда я отступаю

ROLLBACK;
Query OK, 0 rows affected (0.005 sec)

Затем я проверяю снова обновленную запись, я вижу, что данные не меняются. Это странно, потому что я думаю, что данные всегда будут меняться, несмотря ни на что, потому что флаг autocommit включен.

Пожалуйста, объясните мне, почему. Спасибо

1
Trần Kim Dự 2 Май 2019 в 00:29

3 ответа

Лучший ответ

Даже если autocommit включен, если вы используете BEGIN или START TRANSACTION, он временно приостанавливает автоматическое принятие каждого оператора, пока вы не завершите транзакцию.

Вы процитировали страницу руководства https://dev.mysql.com/doc /refman/8.0/en/commit.html, который объясняет:

Чтобы неявно отключить режим автоматической фиксации для одной серии операторов, используйте инструкцию START TRANSACTION:

При START TRANSACTION автоматическая фиксация остается отключенной до тех пор, пока вы не завершите транзакцию с помощью COMMIT или ROLLBACK. Затем режим автоматической фиксации вернется к своему предыдущему состоянию.

(акцент мой)

Другими словами, операторы, которые вы выполняете после BEGIN или START TRANSACTION, не фиксируются автоматически. Это ожидается.

1
Bill Karwin 1 Май 2019 в 21:58

BEGIN - это явное начало транзакции, которое отключает эффект autocommit.

Автокоммит применяется к SQL, который не является явно транзакционным.

1
danblack 1 Май 2019 в 21:45

Хотя предыдущие ответы верны, позвольте мне указать другой угол.

Если вы запустите миллиардную строку UPDATE (что займет несколько часов) и отключите компьютер от сети, UPDATE будет частично завершен. Что происходит после перезагрузки компьютера (и MySQL)? В MyISAM некоторые строки будут обновлены, некоторые - нет. Но с InnoDB он ROLLBACK будет частично завершен UPDATE (и может потребоваться еще несколько часов).

Таким образом, цитата из руководства была не только неоднозначной (как указано в других Ответах), но и была «буквально» неверной. В моем примере изменение can и было отменено.

Мне нравится формулировать это так:

Autocommit=ON, если в транзакции не указано иное, эквивалентно переносу оператора в BEGIN и COMMIT. То есть утверждение выполняется атомарно.

Я подал http://bugs.mysql.com/95414.

1
Rick James 19 Май 2019 в 04:41