Foro de elhacker.net

Programación => PHP => Mensaje iniciado por: gAb1 en 6 Junio 2016, 03:01 am



Título: [Resuelto] mysqli rollback deja de funcionar en php 7
Publicado por: gAb1 en 6 Junio 2016, 03:01 am
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:

Código
  1. public function Upload() {
  2.  
  3.    try {
  4.  
  5.        // rollback should revert here
  6.        // el único cambio es el siguiente
  7.        // $mysqli->query('START TRANSACTION;');
  8.         $mysqli->begin_transaction();
  9.  
  10.        // multiple prepared statements
  11.  
  12.        if ($mysqli->commit()) {
  13.            $exit = $log;
  14.        } else {
  15.            throw new Exception('Transaction commit failed. Property ID: ' . $id);
  16.        }
  17.  
  18.    } catch (Exception $e) {
  19.  
  20.        try {
  21.  
  22.            $test = $this->owner['id'] ? 'property' : ($this->applicant ? 'demand' : 'Fatal Error: PropertyFromInput() contact error (no owner, no applicant)');
  23.  
  24.            $log = 'Rolling back new ' . $test . ' upload' . "\n";
  25.  
  26.            if (!$mysqli->rollback()) $log .= 'no rollback...' . "\n";
  27.  
  28.            if ($test == 'property') $log .= $this->cleanup_prop() ? 'property successfully cleaned up' . "\n" : 'error while cleaning up property' . "\n";
  29.  
  30.            $err_msg = $e->getMessage();
  31.  
  32.        } catch (Exception $f) {
  33.  
  34.            $err_msg .= $f->getMessage();
  35.  
  36.        }
  37.  
  38.        $usr_msg = $upload_err ? $err_msg : 'Se ha producido un error. Por favor contacte con un administrador.';
  39.  
  40.        $log .= 'User triggered an error while uploading a new ' . $test . ".\n" . 'Error message: ' . $err_msg;
  41.  
  42.        $exit = array($log, $usr_msg);
  43.  
  44.    }
  45.  
  46.    $mysqli->autocommit(TRUE);
  47.  
  48.    return $exit;
  49. }

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!


Título: Re: mysqli rollback deja de funcionar
Publicado por: gAb1 en 8 Junio 2016, 18:22 pm
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:

Código
  1. SELECT CONCAT('ALTER TABLE ',TABLE_NAME,' ENGINE=InnoDB;') FROM TABLES
  2. WHERE ENGINE='MyISAM'
  3. AND table_schema = 'mydatabase'

Solo cambiar donde dice 'mydatabase' por el nombre de la vuestra.