Je travaille sur un script PHP qui importe le fichier CSV ( customers.csv
) dans la table MySQL ( customers
).
Avant d'insérer le contenu du fichier CSV dans la table mysql, je sauvegarde d'abord la customers
table d' origine .
J'encapsule tout le processus d'importation (y compris la sauvegarde) dans une transaction mysql (pour tenir compte des cas où CSV est corrompu quelque part au milieu et pour garantir que l'importation est atomique).
Le problème est que ROLLBACK ne semble pas fonctionner lorsque je l'appelle juste après la INSERT INTO
déclaration: lors de la vérification de la base de données via phpMyAdmin, je peux voir la table nouvellement créée ET LES RANGÉES À L'INTÉRIEUR sont toujours présentes après le retour en arrière .
Voici le journal des opérations:
[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" [] []
Je me demande donc pourquoi depsite ROLLBACK
est appelé, la transaction n'est pas annulée. Je comprends que ce CREATE TABLE
n'est pas de nature transactionnelle et ne peut pas être annulé. Mais je supposais que INSERT INTO
parce qu'il s'agit d'insérer des lignes (pas de définir un schéma), SERA en fait transactionnel, et après ROLLBACK, je me retrouverai avec une table de destination vide. Pourquoi n'est-ce pas le cas?
Et voici la sortie SHOW CREATE TABLE customers
(donc ma table est 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
et voici la sortie pour la table de 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
la source
create table
, alorsstart transaction, insert, rollback
?Réponses:
La raison en est que certaines déclarations, comme
CREATE TABLE
provoquent un commit implicite. Vous pouvez les lire dans la documentation: Instructions qui provoquent une validation implicite .Donc, la séquence originale des déclarations:
s'étendra à:
La solution serait de démarrer la transaction (ou une nouvelle) après l'
CREATE TABLE
instruction ou d'utiliser une table temporaire.la source
cause an implicit commit
... Il fallait donc faire ce plan sur le papier de toute façon :) @RolandoMySQLDBA merci également pour la saisie rapide. J'ai lu quelques dizaines de vos réponses l'année dernière et elles m'ont beaucoup aidé !!INSERT
, provoquée par l'instruction DDL, provoque également une validation après l'insertion?Il semble que l'ordre des instructions soit à l'origine du problème.
Dans mon ancien verrouillage de ligne de poste dans innodb de transaction ACID , j'ai nommé 12 instructions qui interrompent une transaction par intermittence. Dans votre cas particulier, c'était la
CREATE TABLE
déclaration.Une fois que vous avez couru à l'
CREATE TABLE
intérieur d'un blocSTART TRANSACTION
...COMMIT/ROLLBACK
, il n'y avait pas de cadre à restaurer.Lancez juste
CREATE TABLE
avantSTART TRANSACTION
et ça devrait aller.Essaie !!!
la source