Ошибка дублирующего ключа не отменяет / откатывает транзакцию mysql - PullRequest
9 голосов
/ 27 октября 2009

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

Это ожидаемое поведение? Если да, то как можно настроить его так, чтобы при возникновении такой ошибки транзакция откатывалась вместо фиксации?

тестовая среда:

CREATE TABLE `test` (  
  `id` int(11) NOT NULL, 
  PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 

BEGIN;
     INSERT INTO test VALUES (5);
     INSERT INTO test VALUES (5);
COMMIT;

ожидаемый результат: таблица test пуста

фактический результат: таблица test содержит одну запись со значением 5

Ответы [ 2 ]

8 голосов
/ 27 октября 2009

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

Он использует внутреннюю точку сохранения, созданную в начале оператора, а затем откатывается до этой точки сохранения.

Это НЕ откатывает всю транзакцию, потому что это могло быть не то, что вы хотели.

Поведение клиента mysql настраивается с помощью параметров командной строки. Он может либо выйти (что означало бы откат), либо продолжить.

Если вы используете свое собственное приложение, то, что оно делает, зависит только от вас.


Mysql не навязывает ПОЛИТИКУ тому, как вы справляетесь со сбоями - он оставляет это за вашим приложением. Поэтому то, что вы делаете с ними, это ваше личное дело - вы можете игнорировать их, если хотите.

3 голосов
/ 22 июля 2010

MySql (и другой SQLAF AFAIK) не выполняет автоматический откат транзакции при возникновении ошибки.

Вы должны объявить обработчик ошибок, который откатит транзакцию:

DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND
BEGIN 
  ROLLBACK; 
  CALL ERROR_ROLLBACK_OCCURRED; 
END;
...