Я работаю над PHP-скриптом, который импортирует файл CSV ( customers.csv
) в таблицу MySQL ( customers
).
Перед тем, как вставить содержимое CSV-файла в таблицу mysql, я сначала создаю резервную копию исходной customers
таблицы.
Я обертываю весь процесс импорта (включая резервное копирование) в транзакцию mysql (чтобы учесть случаи, когда CSV поврежден где-то посередине, и гарантировать, что импорт атомарен).
Проблема в том, что ROLLBACK, похоже, не работает, когда я вызываю его сразу после INSERT INTO
оператора: при проверке базы данных через phpMyAdmin я вижу новую созданную таблицу, и строки внутри нее все еще присутствуют после отката .
Вот журнал операций:
[2015-01-19 14:08:11] DEBUG: "START TRANSACTION" [] []
[2015-01-19 14:08:11] DEBUG: SHOW TABLES LIKE :table_name; [] []
[2015-01-19 14:08:28] DEBUG: CREATE TABLE `customers__20150119_14_08_20` LIKE `customers` [] []
[2015-01-19 14:08:37] DEBUG: INSERT INTO `customers__20150119_14_08_20` SELECT * FROM `customers` [] []
[2015-01-19 14:08:50] DEBUG: "ROLLBACK" [] []
Поэтому интересно, почему ROLLBACK
называется depsite , транзакция не отменена. Я понимаю, что CREATE TABLE
это не транзакционный характер и его нельзя откатить. Но я предполагал, что INSERT INTO
поскольку он имеет дело со вставкой строк (не определяя схему), на самом деле он будет транзакционным, а после ROLLBACK у меня останется пустая таблица назначения. Почему это не так?
И вот вывод SHOW CREATE TABLE customers
(так что моя таблица InnoDb
):
CREATE TABLE `customers` (
`Code` varchar(32) NOT NULL,
`Name` varchar(128) DEFAULT NULL,
`Price` varchar(128) DEFAULT NULL,
PRIMARY KEY (`Code`),
KEY `Price` (`Price`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
и вот вывод для таблицы назначения:
CREATE TABLE `customers__20150119_14_08_20` (
`Code` varchar(32) NOT NULL,
`Name` varchar(128) DEFAULT NULL,
`Price` varchar(128) DEFAULT NULL,
PRIMARY KEY (`Code`),
KEY `Price` (`Price`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
источник
create table
, а затемstart transaction, insert, rollback
?Ответы:
Причина в том, что некоторые утверждения, например,
CREATE TABLE
вызывают неявную фиксацию. Вы можете прочитать о них в документации: Заявления, которые вызывают неявную фиксацию .Итак, оригинальная последовательность утверждений:
будет расширяться в:
Решением будет запуск транзакции (или новой) после
CREATE TABLE
оператора или использование временной таблицы.источник
cause an implicit commit
... Так или иначе, мы должны были сделать этот набросок на бумаге :) Спасибо @RolandoMySQLDBA за быстрый ввод. Я прочитал несколько десятков ваших ответов за последний год, и они мне очень помогли !!INSERT
тем , вызванное утверждением DDL, а также каким - то образом приводит к фиксации после вставки?Похоже, что порядок утверждений вызывает проблему.
В моей старой блокировке пост-записи в транзакции ACID innodb я назвал 12 операторов, которые прерывали транзакцию с перерывами. В вашем конкретном случае это было
CREATE TABLE
утверждение.После того, как вы запустили
CREATE TABLE
внутриSTART TRANSACTION
...COMMIT/ROLLBACK
блока, откатов уже не было.Просто запустите
CREATE TABLE
доSTART TRANSACTION
и все будет в порядке.Попробуйте!
источник