Автоматический откат, если COMMIT TRANSACTION не достигнут - PullRequest
16 голосов
/ 25 мая 2011

Примите во внимание следующее:

START TRANSACTION;

BEGIN;

INSERT INTO prp_property1 (module_name,environment_name,NAME,VALUE) VALUES ('','production','','300000');

/** Assume there is syntax error SQL here...**/
Blah blah blah

DELETE FROM prp_property1 WHERE environment_name = 'production';

COMMIT TRANSACTION;

Вопрос:

Я заметил, что транзакция автоматически откатывается, и попытка вставки записи завершается неудачей.

Если я не предоставляю обработчик ошибок или проверку ошибок вместе с ROLLBACK TRANSACTION, как указано выше, безопасно ли это, как кажется, выполнять работу в примере, подобном приведенному выше, поскольку COMMIT TRANSACTION никогда не выполняется? *

Я предполагаю, что транзакция откатывается немедленно и отбрасывается, как только возникает ошибка.

Ответы [ 5 ]

22 голосов
/ 25 мая 2011

Нет, транзакции не откатываются, как только возникает ошибка.Но вы можете использовать клиентское приложение, которое применяет эту политику.

Например, если вы используете клиент командной строки mysql, он обычно останавливается при возникновении ошибки и завершается.Выход из транзакции в процессе выполнения вызывает ее откат.

Когда вы пишете свое собственное приложение, вы можете контролировать политику отката, но есть некоторые исключения:

  • Выход (т. Е. Отключение от базы данных) всегда откатывает текущую транзакцию
  • Тайм-аут блокировки или ожидания блокировки неявно вызывает откат

Если не считать эти условиявызовите команду, которая генерирует ошибку, ошибка возвращается как обычно, и вы можете делать все, что захотите, в том числе в любом случае совершить транзакцию.

8 голосов
/ 12 марта 2012

Вы можете использовать процедуру , чтобы сделать это более эффективно.
Транзакция с хранимой процедурой в MySQL Server

6 голосов
/ 05 октября 2015

Использовать хранимую процедуру Mysql

   BEGIN

   DECLARE exit handler for sqlexception
      BEGIN
      ROLLBACK;
   END;

   DECLARE exit handler for sqlwarning
     BEGIN
     ROLLBACK;
   END;

   START TRANSACTION;

   INSERT INTO prp_property1 (module_name,environment_name,NAME,VALUE) VALUES ('','production','','300000');

   [ERROR]

   COMMIT;

   END

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

4 голосов
/ 16 июня 2016

Я хотел бы добавить к тому, что @MarkR уже сказал.Обработка ошибок при условии наличия механизма InnoDB происходит, как описано в документации Mysql Server

  • Если у вас заканчивается файловое пространство в табличном пространстве, MySQL Table is full errorпроисходит, и InnoDB откатывает инструкцию SQL.
  • В результате тупика транзакции InnoDB откатывает всю транзакцию.
  • Ошибка дублирующегося ключа откатывает инструкцию SQL
  • Aстрока слишком длинная ошибка откатывает оператор SQL.
  • Другие ошибки в основном обнаруживаются уровнем кода MySQL (выше уровня механизма хранения InnoDB), и они откатывают соответствующий оператор SQL

Насколько я понимаю, когда сеанс Mysql заканчивается (когда заканчиваются скрипты php), все, что не зафиксировано, откатывается.Я все еще должен найти действительно надежный источник, чтобы поддержать это утверждение, поэтому не верьте мне на слово.

0 голосов
/ 24 августа 2018

Я проверил эти три ситуации;MySQL не выполняет откат автоматически.

В результате тупика транзакции InnoDB откатывает всю транзакцию.Ошибка повторяющегося ключа откатывает инструкцию SQL. Слишком длинная строка ошибки откатывает инструкцию SQL.

Сбой только для затронутых записей, остальные записи завершаются успешно, если приложение не вызывает явный откат.*

...