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
źródło
create table
, a potemstart transaction, insert, rollback
?Odpowiedzi:
Powodem jest to, że niektóre instrukcje, na przykład,
CREATE TABLE
powodują niejawne zatwierdzenie. Możesz o nich przeczytać w dokumentacji: Oświadczenia, które powodują niejawne zatwierdzenie .Oryginalna sekwencja instrukcji:
rozwinie się w:
Rozwiązaniem byłoby rozpocząć transakcję (lub nową) po
CREATE TABLE
wyciągu lub użyć tabeli tymczasowej.źródło
cause an implicit commit
... Więc musiałem zrobić ten zarys na papierze :) @RolandoMySQLDBA również dziękuję za szybkie wejście. W ubiegłym roku przeczytałem kilkadziesiąt waszych odpowiedzi i bardzo mi pomogły !!INSERT
, spowodowane rachunku telefonicznego, również w jakiś sposób powoduje popełnić po wkładki?Wygląda na to, że problem powoduje kolejność instrukcji.
W moim starym wierszu blokowania wiersza w ramach transakcji ACID innodb nazwałem 12 instrukcji przerywających transakcję sporadycznie. W twoim konkretnym przypadku było to
CREATE TABLE
stwierdzenie.Po uruchomieniu
CREATE TABLE
wSTART TRANSACTION
...COMMIT/ROLLBACK
bloku nie było żadnych ram do wycofania.Po prostu uruchom
CREATE TABLE
wcześniejSTART TRANSACTION
i wszystko powinno być w porządku.Spróbuj !!!
źródło