Pracuję nad skryptem PHP, który importuje plik CSV ( customers.csv
) do tabeli MySQL ( customers
).
Przed wstawieniem zawartości pliku CSV do tabeli mysql najpierw tworzę kopię zapasową oryginalnej customers
tabeli.
Zawijam cały proces importu (w tym tworzenie kopii zapasowej) w transakcji mysql (aby uwzględnić przypadki, w których CSV jest uszkodzony gdzieś pośrodku i aby upewnić się, że import jest atomowy).
Problem polega na tym, że funkcja ROLLBACK nie działa, gdy wywołuję ją zaraz po INSERT INTO
instrukcji: podczas sprawdzania bazy danych za pomocą phpMyAdmin widzę nowo utworzoną tabelę ORAZ WIERSZE WEWNĄTRZ po jej wywołaniu .
Oto dziennik operacji:
[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" [] []
Zastanawiam się więc, dlaczego nazywa się depsite ROLLBACK
, transakcja nie jest anulowana. Rozumiem, że CREATE TABLE
nie ma charakteru transakcyjnego i nie można go wycofać. Ale zakładałem, że INSERT INTO
ponieważ zajmuje się wstawianiem wierszy (nie definiowaniem schematu), BĘDZIE faktycznie transakcyjne, a po ROLLBACK pozostanie pusta tabela docelowa. Dlaczego tak nie jest?
A oto wynik SHOW CREATE TABLE customers
(więc moja tabela jest 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
a oto dane wyjściowe dla tabeli desination:
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
, a potemstart transaction, insert, rollback
?