Hace poco me cambie de hosting y le instale la ultima versión de php. Ahora el rollback no hace nada: no da error, el if en el que lo puse da true siempre y los datos se siguen insertando.
Antes usaba php 5.4 y así es como tenia mi script:
public function Upload() {
try {
// rollback should revert here
// el único cambio es el siguiente
// $mysqli->query('START TRANSACTION;');
$mysqli->begin_transaction();
// multiple prepared statements
if ($mysqli->commit()) {
$exit = $log;
} else {
throw new Exception('Transaction commit failed. Property ID: ' . $id);
}
} catch (Exception $e) {
try {
$test = $this->owner['id'] ? 'property' : ($this->applicant ? 'demand' : 'Fatal Error: PropertyFromInput() contact error (no owner, no applicant)');
$log = 'Rolling back new ' . $test . ' upload' . "\n";
if (!$mysqli->rollback()) $log .= 'no rollback...' . "\n";
if ($test == 'property') $log .= $this->cleanup_prop() ? 'property successfully cleaned up' . "\n" : 'error while cleaning up property' . "\n";
$err_msg = $e->getMessage();
} catch (Exception $f) {
$err_msg .= $f->getMessage();
}
$usr_msg = $upload_err ? $err_msg : 'Se ha producido un error. Por favor contacte con un administrador.';
$log .= 'User triggered an error while uploading a new ' . $test . ".\n" . 'Error message: ' . $err_msg;
$exit = array($log, $usr_msg);
}
$mysqli->autocommit(TRUE);
return $exit;
}
Antes funcionaba y ahora ya no. Supongo que se debe a los cambios que ha sufrido php desde entonces.
Estuve leyendo un poco y al parecer decidieron (al fin) implementar el bloque finally, en php 5.5. El otro cambio relevante a esto fue en php 7 donde se mejora el manejo de errores.
Pero sigo sin estar seguro de donde puede estar el fallo. La única utilidad que le veo a finally en mi caso sería poner el autocommit, por que el return deberia ir fuera. Y no sé que más puede estar fallando.
¿Alguna idea? Gracias!
Dejo la solución por si a alguien le ocurre:
Mi problema fue que uso kloxomr7 y este por defecto (por motivos de rendimiento) cambia el engine de la base de datos a MyISAM y las transacciones solo son compatibles con InnoDB.
Una rápida y facil solución sería ejecutando la siguiente query para la base de datos a cambiar:
SELECT CONCAT('ALTER TABLE ',TABLE_NAME,' ENGINE=InnoDB;') FROM TABLES
WHERE ENGINE='MyISAM'
AND table_schema = 'mydatabase'
Solo cambiar donde dice 'mydatabase' por el nombre de la vuestra.