Ejemplo completo

Veamos un ejemplo de uso de transacciones usando mysqli con objetos. En la base de datos UAZON tenemos una tabla **pedidos** y otra tabla **libros_pedidos** que contiene las líneas de pedidos del carro de la compra. En la imagen siguiente podemos ver el diseño EER de las tablas implicadas cuando un usuario confirma el pedido y éste se inserta en la base de datos. Las tablas relacionadas son: **USUARIOS**, **LIBROS**, **PEDIDOS** y **LIBROS_PEDIDOS**

EER: Entidad Relación Extendido

Tablas relacionadas para en la inserción de un pedido y sus líneas.

La tabla **pedidos** contiene una clave ajena ( **fk_usuarios**) a la tabla **usuarios.** La tabla **libros_pedidos** contiene dos claves ajenas: **fk_pedidos** y **fk_libros**, una que apunta a la tabla **pedidos** y otra que apunta a la tabla **libros**. La columna **fk_pedidos** nos obliga a insertar primeramente el pedido y posteriormente obtener ese número de pedido para insertarlo en la tabla **libros_pedidos**. Este ejemplo es ideal para que usemos transacciones, ya que, si algunas de las inserciones falla, las anteriores inserciones no deben persistirse en base de datos. Tendríamos que realizar un rollback de la transacción.

En esto ejemplo vamos a introducir un pedido con coste total de '101.25' euros, fecha '2008-11-17' y por último el identificador de usuario '2' ("_Francisco Rubio Blancas_"). Como línea de pedidos vamos a insertar dos libros con identificador '1' (_Anna Karenina_), la clave ajena del pedido ($fk_libros que lo obtendremos de la propiedad **insert_id** del objeto MySQLI), como cantidad '2' y como precio '44.00' (precio actual del libro 22.00 € por 2)

Este sería el código:

<?php
try
{
   $db = new mysqli("localhost", "comprador", "proweb2013", "uazon");

   if (mysqli_connect_errno() != 0) {
      throw new Exception('Error conectando: ' .
         mysqli_connect_error(), mysqli_connect_errno());
   }
   // Forzamos transacciones manuales, el motor NO puede ser MyISAM
   if ($db->autocommit(false) === false)
      throw new Exception('El motor no admite transacciones');

   try
   {
      //El usuario Francisco Rubio Blancas tiene por id un 2 por lo que
      //$fk_usuario = 2 - Francisco Rubio Blancas
      //Total del pedido 101.25
      //Fecha del pedido formato MySQL 2013-10-17
      $consulta = "INSERT INTO pedidos(total, fecha, fk_usuarios) " .
         "VALUES ('101.25', '2013-10-17', '2')";

      if ($db->query($consulta) === false)
         throw new ExcepcionEnTransaccion("SQL Incorrecta: " + $consulta);

      //Nos guardamos el ultimo id insertado (autoincremento)
      $fk_pedidos = $db->insert_id;
      // Vamos a comprar 2 libros de Anna Karenina
      // cuyo id es igual 1: 22.00 x 2 = 44.00

      $consulta =
         "INSERT INTO libros_pedidos(fk_libros, fk_pedidos, cantidad,precio) " .
         "VALUES('1', '$fk_pedidos', '2', '44.00')";
      if ($db->query($consulta) === false)
         throw new ExcepcionEnTransaccion("SQL Incorrecta: " + $consulta);

      // Si hemos podido realizar todas las transacciones forzamos
      // la escritura en la base de datos.
      $db->commit();
      echo 'Pedido insertado correctamente.';
   }
   catch (ExcepcionEnTransaccion $e) {
      echo 'No se ha podido realizar la insercion correctamente.';
      echo $e;
      // Si alguno de los insert falla no realizamos
      // ninguna insercion, eliminando cualquier insert pendiente en la
      // transaccion actual antes del ultimo commit.
      $db->rollback();
   }
   $db->close();
}
catch (Exception $e) {
   echo $e->getMessage();
   if (mysqli_connect_errno() == 0)
      $db->close(); exit();
}
?>

results matching ""

    No results matching ""