Получают ли вставки автоматически совершенные?

13

Наше приложение запускает запрос INSERT к базе данных MySQL для добавления записей. Я хочу знать, автоматически ли фиксируются записи. Если я запускаю команду ROLLBACK, когда база данных выполняет откат? Возможен ли ROLLBACK после COMMIT?

RPK
источник
Просто для пояснения, я отметил как 'innodb' 19 часов назад, так как InnoDB использует COMMIT / ROLLBACK.
RolandoMySQLDBA
Это дает +1 за напоминание разработчикам и администраторам баз данных о поведении транзакций, соответствующих парадигмах приложений, поддерживающих транзакции, и их последствиях (хороших или плохих).
RolandoMySQLDBA
Я ответил на ваш вопрос с комментарием под моим ответом.
RolandoMySQLDBA

Ответы:

10

Ответ на ваш вопрос зависит от того, участвуете ли вы в транзакции, которая будет охватывать более одного утверждения. (Вы пометили вопрос с InnoDB, ответ был бы другим с MyISAM.)

Из справочного руководства: http://dev.mysql.com/doc/refman/5.1/en/commit.html

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

Так что да, по умолчанию, если вы просто используете INSERT, вставленные вами записи будут зафиксированы, и нет смысла откатывать их назад. (Это фактически то же самое, что оборачивать каждое утверждение между BEGINи COMMIT.)

Однако, если вы имеете дело с транзакциями в явном виде, вам придется использовать COMMITдля фиксации хранения записей, но вы также сможете использовать ROLLBACK.

Вы можете начать транзакцию явно с помощью START TRANSACTION(или BEGIN). Это не зависит от autocommitнастройки (по умолчанию включено):

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

В качестве альтернативы, если autocommit=0, я думаю, какое-либо утверждение, следующее за другим концом транзакции, начнет транзакцию (но вы все равно можете использовать START TRANSACTIONявно); что , по крайней мере, как я интерпретировать это :

Режим автоматической фиксации. Если установлено значение 1, все изменения в таблице вступают в силу немедленно. Если установлено значение 0, вы должны использовать COMMIT для принятия транзакции или ROLLBACK для ее отмены. Если autocommit равен 0 и вы измените его на 1, MySQL автоматически выполнит COMMIT любой открытой транзакции. Другой способ начать транзакцию - использовать оператор START TRANSACTION или BEGIN. См. Раздел 12.3.1, «Синтаксис START TRANSACTION, COMMIT и ROLLBACK».

Более конкретно, «другой способ начать транзакцию», по-видимому, подразумевает, что установки «autocommit = 0» достаточно для запуска транзакции (по крайней мере, непосредственно перед каждым оператором в начале сеанса или после COMMIT/ ROLLBACK). Я бы предложил использовать BEGINили START TRANSACTIONявно в любом случае, даже если autocommit=0, поскольку это может сделать его более понятным, чтобы увидеть, когда транзакция начинается или заканчивается.

(Способ запуска транзакции может зависеть от того, как ваше приложение использует MySQL.)

Bruno
источник
1
Заслуживает +1 для полного определения транзакционных протоколов.
RolandoMySQLDBA
@ Bruno, для MyISAM, где «commit» и «rollback» не работают, разве вставки не будут наполовину зафиксированы?
Pacerier
7

По умолчанию для InnoDB установлено значение autocommit = 1 или ON . После совершения они не могут быть отменены .

Вам нужно будет сделать одну из двух вещей, чтобы отключить его в будущем:

ВАРИАНТ 1: Добавьте это в /etc/my.cnf и перезапустите mysql

[mysqld]
autocommit=0

ВАРИАНТ 2: Выполните одно из этих действий в открытом подключении к БД перед началом любого значимого SQL

SET autocommit = 0;
START TRANSACTION;

Под этими двумя вариантами вам придется выполнить ручной COMMIT или ручной ROLLBACK .

ПРЕДОСТЕРЕЖЕНИЕ

Если таблица MyISAM, то объяснение проще. Поскольку для механизма хранения MyISAM нет транзакций, все выполняемые операции INSERT, UPDATE и DELETE являются постоянными. Никаких откатов вообще.

RolandoMySQLDBA
источник
Для дополнительного пояснения мой ответ касается как хранилищ InnoDB, так и MyISAM.
RolandoMySQLDBA
1
На всякий случай, если автоматическая фиксация отключена в InnoDB, и мое приложение запускает запросы вставки, и я забываю выполнить фиксацию, как скоро будут потеряны изменения?
RPK
Если ваше приложение вручную запускает COMMIT после каждой вставки, оно записывается и не может быть удалено. Если соединение с БД прекращается до того, как вы ВЫБЕРИТЕ, все изменения будут потеряны и произойдет откат. Если вы выполняете какой-либо DDL (CREATE TABLE, DROP TABLE, ALTER TABLE и т. Д.) Или вручную запускаете блокировку таблицы, вставки автоматически загружаются. Если вы используете START TRANSACTION, все незафиксированные изменения фиксируются.
RolandoMySQLDBA
1
Относительно «Если вы используете START TRANSACTION, все незафиксированные изменения фиксируются». (в контексте DDL, в противном случае это будет отменено), существует также неявный коммит до (неявный коммит после - с версии 5.5.3 согласно документации).
Бруно
1
«Если вы используете START TRANSACTION, все незафиксированные изменения фиксируются». - Я получил эту идею из Руководства по изучению сертификации MySQL 5.0 (ISBN 0-672-32812-7), в котором указаны START TRANSACTION, SET AUTOCOMMIT = 1, LOCK TABLES, UNLOCK TABLES, TRUNCATE TABLE, RENAME TABLE, DROP INDEX, DROP TABLE , DROP DATABASE, CREATE INDEX, BEGIN и ALTER TABLE под заголовками «При некоторых обстоятельствах текущая транзакция может неявно завершиться: если вы выполните какой-либо из следующих операторов, InnoDB неявно фиксирует предыдущие незавершенные операторы текущей транзакции и начинает новая транзакция ".
RolandoMySQLDBA