Estoy trabajando en un script PHP que importa el archivo CSV ( customers.csv
) en la tabla MySQL ( customers
).
Antes de insertar el contenido del archivo CSV en la tabla mysql, primero estoy haciendo una copia de seguridad de la customers
tabla original .
Estoy envolviendo todo el proceso de importación (incluida la copia de seguridad) en una transacción mysql (para tener en cuenta los casos en que CSV está dañado en algún punto intermedio y para garantizar que la importación sea atómica).
El problema es que ROLLBACK no parece funcionar cuando lo llamo justo después de la INSERT INTO
declaración: cuando verifico la base de datos a través de phpMyAdmin, puedo ver la tabla recién creada Y LAS FILAS DENTRO DE ELLA todavía están presentes después del roollback .
Aquí está el registro de las operaciones:
[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" [] []
Entonces, me pregunto por qué ROLLBACK
se llama depsite , la transacción no se cancela. Entiendo que CREATE TABLE
no es de naturaleza transaccional y no se puede revertir. Pero suponía que INSERT INTO
debido a que se trata de insertar filas (sin definir el esquema), SERÁ realmente transaccional, y después de ROLLBACK me quedaré con la tabla de destino vacía. ¿Por qué no es el caso?
Y aquí está la salida SHOW CREATE TABLE customers
(entonces mi tabla es 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
y aquí está la salida para la tabla de destino:
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
fuente
create table
, entoncesstart transaction, insert, rollback
?Respuestas:
La razón es que algunas declaraciones, como
CREATE TABLE
causar una confirmación implícita. Puede leer sobre ellos en la documentación: Declaraciones que causan un compromiso implícito .Entonces la secuencia original de declaraciones:
se expandirá a:
La solución sería comenzar la transacción (o una nueva) después de la
CREATE TABLE
declaración o usar una tabla temporal.fuente
cause an implicit commit
... Así que tuve que hacer este esquema en papel de todos modos :) @RolandoMySQLDBA gracias por su rápida aportación también. ¡He leído algunas docenas de sus respuestas en el último año y me ayudaron mucho!INSERT
, causado por la instrucción DDL, también causa un commit después del insert?Parece que el orden de las declaraciones está causando el problema.
En mi antiguo bloque de la fila posterior dentro de la transacción ACID innodb , nombré 12 declaraciones que interrumpen una transacción de forma intermitente. En su caso particular, fue la
CREATE TABLE
declaración.Una vez que corriste
CREATE TABLE
dentro de unSTART TRANSACTION
...COMMIT/ROLLBACK
bloque, no había marco para revertir.Simplemente ejecute el
CREATE TABLE
antesSTART TRANSACTION
y debería estar bien.Darle una oportunidad !!!
fuente