MySQL: флаг автоматической фиксации включен, но транзакция все еще может откатываться - PullRequest
1 голос
/ 02 мая 2019

Я использую версию 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 включен.

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

Ответы [ 3 ]

1 голос
/ 02 мая 2019

Даже если 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 голос
/ 19 мая 2019

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

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

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

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

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

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

1 голос
/ 02 мая 2019

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

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

...