Автоматический откат, если COMMIT TRANSACTION не достигнута

Рассмотрим следующее:

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 никогда не выполняется?

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

Ответы

Ответ 1

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

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

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

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

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

Ответ 3

Использовать хранимую процедуру 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

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

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

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