Vissa uttalanden (främst DDL ) i MySQL orsaka en implicit commit före de körs och kan inte återställas - som sådant förhindrar detta att de tidigare DML-ändringarna också återställs.
De uttalanden som listas i det här avsnittet (och eventuella synonymer för dem) avslutar implicit alla transaktioner som är aktiva i den aktuella sessionen, som om du hade gjort en COMMIT innan du körde uttalandet . Från och med MySQL 5.5.3 orsakar de flesta av dessa uttalanden också en implicit commit efter exekvering; för ytterligare information, se slutet av det här avsnittet.
Sedan ALTER TABLE
är en av de berörda satserna, behandlas SQL-batchen effektivt som:
START TRANSACTION;
INSERT INTO `users` VALUES(NULL, 'User A', '[email protected]', '4', 'User A');
COMMIT; -- prevents ROLLBACK of insert(s), even if DDL fails
ALTER TABLE `users` CHANGE `level` `level` TINYINT(3) UNSIGNED NOT NULL;
Den föreslagna lösningen är att hålla DDL och DML åtskilda . dokumentationen säger:
Du bör utforma dina [DML]-transaktioner så att de inte inkluderar sådana [DDL]-satser. Om du utfärdar ett uttalande tidigt i en transaktion som inte kan återställas, och sedan ett annat uttalande senare misslyckas, kan den fulla effekten av transaktionen inte återställas i sådana fall genom att utfärda ett ROLLBACK-uttalande.