php - manejar - MySQL InnoDB-Confundido sobre transacciones
transacciones php sql server (3)
Debe verificarlo manualmente y si hay algún error, necesita deshacerlo usted mismo.
He estado usando MySQL durante muchos años, pero no tengo mucha experiencia en el uso del motor InnoDB.
Estoy realizando algunas pruebas ahora, ya que voy a usarlo y, por lo que he leído, se supone que no debe permitir que algo "funcione" si hay algún problema con alguna de las consultas en ESA transacción.
Mi pregunta es por qué, en el siguiente código ... ¿todavía ingresa las dos primeras consultas en la base de datos cuando claramente hay un problema con la tercera consulta?
$query = "BEGIN";
mysql_query($query);
$query = "INSERT INTO list_columns(lid,column_name) VALUES(8,''test'')";
mysql_query($query);
$query = "INSERT INTO list_columns(lid,column_name) VALUES(8,''test'')";
mysql_query($query);
$query = "INSERT INT list_columns(lid,column_name) VALUES(8,''test'')";
mysql_query($query);
$query = "COMMIT";
mysql_query($query);
Editar: Entiendo sobre el uso de ROLLBACK y todo ... pero pensé que el propósito de las transacciones era que si había algún problema con alguna de las consultas en la transacción, NINGUNO de ellas se ejecutara ... o solo este es el caso con varias inserciones en una consulta, por ejemplo ... si una de las inserciones presenta un problema, ¿no se insertará ninguna?
Para agregar a lo que dijo Konerak ... este es un proceso simplificado con PDO en lugar de mysql
por ejemplo:
$pdo = new PDO($mysqldsn, $user, $pass);
$pdo->beginTransaction();
try {
$pdo->query("INSERT INTO list_columns(lid,column_name) VALUES(8,''test'')");
$pdo->query("INSERT INTO list_columns(lid,column_name) VALUES(8,''test'')");
$pdo->query("INSERT INT list_columns(lid,column_name) VALUES(8,''test'')");
$pdo->commit();
} catch (PDOException $e) {
$pdo->rollBack();
throw $e;
}
Si el problema es algo así como " Este inserto viola una clave única ", se llevará a cabo la confirmación. Debe verificarse si la consulta arrojó errores, y si es así, ROLLBACK
.
Si el problema es, por ejemplo, un cierre inesperado del servidor, las consultas 1 y 2 no se llevarán a cabo.
Por supuesto, ya que sus 3 consultas aquí son las mismas, este es un ejemplo tonto. Al menos cambiar la lid
para ver. ¿Por qué no haces una prueba rápida?
Editar: editó su pregunta sobre el propósito de las transacciones.
El objetivo de las transacciones es mantener la base de datos en un estado coherente (leer en ACID ), pero le corresponde al programador decidir qué es coherente. Mire la respuesta de prodigitalson para ver un ejemplo de una posible captura de error de php que hace esto por usted. Pero mientras está en una transacción, otros procesos no verán los cambios que está haciendo su transacción, por lo tanto, serán atómicos y aislados.
CREATE TABLE `testkeys` (
`lid` INT,
`column_name` VARCHAR(50),
UNIQUE KEY `testuniq` (`lid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
BEGIN;
INSERT INTO testkeys(lid,column_name) VALUES(1,''test 1'');
INSERT INTO testkeys(lid,column_name) VALUES(2,''test 2'');
INSERT INTO testkeys(lid,column_name) VALUES(3,''test 3'');
INSERT INTO testkeys(lid,column_name) VALUES(2,''test 2b'');
COMMIT;