Usando transacciones en bases de datos

9798 단어 database
Al escribir la lógica de una aplicación que interactúa con una base de datos relacional
para almacenar la información, generalmente se puede tener varios
pasos para guardar cada pedazo en un lugar específico de la base, las bases de datos denominadas
ACID Tienen una herramienta poderoza para evitar inconsistencias de datos
hoy nos concentraremos en la A de ACID Atomicidad.

기본 설정에 따라 문서를 작성할 필요가 없습니다.
se Tiene varias tablas como: factura , detalle_factura , inventario , producto 등. Al Envira la información
desde la interfaz de usuario hacia la aplicación podemos tener una sola estructura con todos los
datos necesarios para crear la factura, pero a nivel de aplicación debemos analizar esa estructura
y leerla para que cada parte se guarde en una tabla específica de la base de datos, de tal forma
que tenremos un registro para factura con los datos de la cabecera, varios registros de detalle_facturay adicionalmente se debe modificar las cantidades de los productos en el detalle del inventario 데 카다 producto .

Si tomamos la vía rápida de hacerlo todo esperando que nada fall, tenremos codigo cómo:

<?php

// ... solo el código que interesa para el ejemplo
$factura = new Factura($datosDeFactura);
$factura->save();
foreach ($detalleDeFactura as $detalle) {
    $detalle = new DetalleFactura($detalle);
    $detalle->factura = $factura;
    $detalle->producto = Producto::findOrFail($detalle['producto_id']);
    $detalle->save();

    $inventario = new Inventario($detalle);
    $inventario->producto = Producto::findOrFail($detalle['producto_id']);
    $inventario->save();
}


Como podemos ver estamos usando algún tipo de ORM en el que creamos los objetos con datos y guardamos cada uno,
el problema sucede si digamos en la estructura de datos Envirada, uno de los producto_id 생산물이 없습니다.
De tal forma que si Enviramos una lista con 3 productos y el último id no está definido, en este codigo se creará
una factura con 2 detalles y 2 afectaciones a inventario, en el ultimo producto el sistema dará un fallo y no podrá
seguir, pero en la base de datos ya se escribió parte de la información.

Para solucionar este gran inconveniente debemos usar una herramienta que todas las bases de datos relacionales
타이넨, TRANSACCIONES.

A nivel de base de datos desde un cliente por ejemplo, es fácil comenzar una transacción con el comando:

BEGIN;


Luego se puede hacer varias operaciones de lectura y/o escritura:

INSERT INTO `factura` (numero, fecha, estado) 
VALUES ('001-001-1000', '2021-05-27', 'Facturada');

INSERT INTO `detalle_factura` (item, producto_id, cantidad, precio) 
VALUES ('1', 2000, 1, 500);


Al final se puede decidir siguardo todos los cambios o regreso al estado original antes de enienar el comando BEGIN. 시 데서 에스크리비르
COMMIT, si quiero descartar todos los cambios uso el comando ROLLBACK.

COMMIT;
--- o 
ROLLBACK;


Esto nos asegura que en el COMMIT todas las operaciones realizadas se ejecutan como una sola operación o no se ejecuta nada,
a esto se le llama ATOMICIDAD.

En nuestro ejemplo de php, se puede Implementar de varias formas, pero la que normalmente uso es hacer un try catch.

<?php

// ... solo el código que interesa para el ejemplo

try {
    $conexionBd->begin();

    $factura = new Factura($datosDeFactura);
    $factura->save();
    foreach ($detalleDeFactura as $detalle) {
        $detalle = new DetalleFactura($detalle);
        $detalle->factura = $factura;
        $detalle->producto = Producto::findOrFail($detalle['producto_id']);
        $detalle->save();

        $inventario = new Inventario($detalle);
        $inventario->producto = Producto::findOrFail($detalle['producto_id']);
        $inventario->save();
    }

    $conexionBd->commit();
} 
catch (\Exception $e)
{
    $conexionBd->rollback();
    throw $e;
}


Agregando estas líneas de código estamos asegurando que la factura se crea con los 3 productos enienados, o no se crea la factura, y
la integridad de los datos está asegurada sin datos basura en la base.

좋은 웹페이지 즐겨찾기