Ich arbeite an einem PHP-Skript, das CSV-Datei ( customers.csv
) in MySQL table ( customers
) importiert .
Bevor ich den Inhalt der CSV-Datei in die MySQL-Tabelle einfüge, sichere ich zuerst die ursprüngliche customers
Tabelle.
Ich verpacke den gesamten Importprozess (einschließlich der Sicherung) in eine MySQL-Transaktion (um Fälle zu berücksichtigen, in denen CSV irgendwo in der Mitte beschädigt ist, und um sicherzustellen, dass der Import atomar ist).
Das Problem ist, dass ROLLBACK nicht zu funktionieren scheint, wenn ich es direkt nach der INSERT INTO
Anweisung aufrufe: Wenn ich die Datenbank über phpMyAdmin überprüfe, sehe ich die neu erstellte Tabelle UND REIHEN INNERHALB, die nach dem Roollback noch vorhanden sind .
Hier ist das Protokoll der Operationen:
[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" [] []
Ich frage mich also, warum depsite ROLLBACK
aufgerufen wird und die Transaktion nicht abgebrochen wird. Ich verstehe, dass dies CREATE TABLE
nicht transaktionaler Natur ist und nicht zurückgesetzt werden kann. Aber ich ging davon aus, dass, INSERT INTO
da es sich um das Einfügen von Zeilen handelt (ohne das Schema zu definieren), tatsächlich transaktional sein wird und nach ROLLBACK eine leere Zieltabelle übrig bleibt. Warum ist das nicht der Fall?
Und hier ist die Ausgabe SHOW CREATE TABLE customers
(so ist meine Tabelle 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
und hier ist die Ausgabe für die Zieltabelle:
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
quelle
create table
, dannstart transaction, insert, rollback
?Antworten:
Der Grund ist, dass einige Anweisungen, wie z. B.
CREATE TABLE
ein implizites Commit verursachen. Sie können darüber in der Dokumentation lesen: Anweisungen, die ein implizites Commit verursachen .Also die ursprüngliche Reihenfolge der Aussagen:
wird erweitern in:
Die Lösung wäre, die Transaktion (oder eine neue) nach der
CREATE TABLE
Anweisung zu starten oder eine temporäre Tabelle zu verwenden.quelle
cause an implicit commit
... Also musste ich diese Gliederung sowieso auf Papier machen :) @RolandoMySQLDBA danke auch für die schnelle Eingabe. Ich habe im letzten Jahr einige Dutzend Ihrer Antworten gelesen und sie haben mir sehr geholfen !!INSERT
, verursacht durch die DDL-Anweisung, auch irgendwie ein Festschreiben nach dem Einfügen verursacht?Es sieht so aus, als ob die Reihenfolge der Anweisungen das Problem verursacht.
In meiner alten Post- Row-Sperre innerhalb der ACID-Transaktion innodb habe ich 12 Anweisungen benannt, die eine Transaktion zeitweise unterbrechen. In Ihrem speziellen Fall war es die
CREATE TABLE
Aussage.Sobald Sie
CREATE TABLE
in einemSTART TRANSACTION
...COMMIT/ROLLBACK
Block gelaufen sind , gab es kein Framework zum Zurücksetzen.Führen Sie einfach das
CREATE TABLE
vorherSTART TRANSACTION
und Sie sollten in Ordnung sein.Versuche es !!!
quelle