En SQL, al realizar cambios masivos, a menudo se requiere implementar un escenario de 'todo o nada' — o todos los cambios se llevan a cabo, o se revierten ante cualquier error. Este enfoque se logra mediante el uso de transacciones. El procedimiento almacenado debe iniciar explícitamente una transacción (BEGIN TRANSACTION), envolver las operaciones correspondientes, manejar errores, y en caso de falla ejecutar ROLLBACK, de lo contrario — COMMIT.
No se debe olvidar manejar correctamente los errores a través de constructos como TRY...CATCH (SQL Server) o EXCEPTION (PostgreSQL).
Ejemplo para SQL Server:
CREATE PROCEDURE MassUpdate AS BEGIN BEGIN TRY BEGIN TRANSACTION; UPDATE Orders SET Status = 'Processed' WHERE Status = 'Pending'; UPDATE Inventory SET Stock = Stock - 1 WHERE ProductID IN (SELECT ProductID FROM Orders WHERE Status = 'Processed'); COMMIT TRANSACTION; END TRY BEGIN CATCH ROLLBACK TRANSACTION; -- Registro del error THROW; END CATCH END
Pregunta: ¿Es suficiente utilizar solo BEGIN TRANSACTION y COMMIT para garantizar el retroceso correcto de cambios ante errores en todos los sistemas de gestión de bases de datos soportados?
Respuesta: No, la transacción en sí misma no captura excepciones. Es necesario usar manejadores (TRY...CATCH o equivalentes) para atrapar el error y llamar explícitamente a ROLLBACK. En algunos SGBD (por ejemplo, MySQL con autocommit) también puede ser necesaria una configuración adicional.
Ejemplo de código incorrecto (SQL Server):
BEGIN TRANSACTION; UPDATE Users SET Name = 'Ivan' WHERE ID = 1; UPDATE Orders SET Amount = Amount/0 WHERE UserID = 1; -- Error de división por 0 COMMIT TRANSACTION;
En este caso, si ocurre un error, la transacción seguirá abierta, y los cambios en la primera tabla pueden guardarse.
Historia
En un proyecto de tienda en línea se olvidó el manejo de errores en las transacciones, lo que llevó a la pérdida parcial de datos relacionados: si al actualizar un pedido ocurría un problema al actualizar el stock, solo parte de los cambios se revertía, comprometiendo la integridad de la información.
Historia
En un proyecto de análisis BI se implementó un recálculo masivo de informes a través de un procedimiento sin un control explícito de transacciones y captura de errores. Resultado: parte de los informes se actualizaron, otros no. Los datos finales resultaron inconsistentes, ya que las situaciones de emergencia no llevaron a un retroceso atómico.
Historia
En una compañía se confiaron erróneamente en autocommit en MySQL, sin establecer el modo de transacciones para operaciones grandes. Ante una falla del servidor, parte de los datos ya se habían grabado, otros no, lo que generó largos trabajos de recuperación y la pérdida de parte de los pedidos.