ошибка дубликата ключа не отменяет/откат транзакции mysql


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

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

Тест окружающая среда:

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 9

2 ответа:

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

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

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

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

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

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

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

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


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