Imagina que estás escribiendo un libro. Pero claro, no siempre todo sale según lo planeado. A veces escribes un capítulo entero, pero al releerlo te das cuenta de que el quinto párrafo quedó fatal. ¿Qué haces? No tiras todo el capítulo a la basura, ¿verdad? En vez de eso, editas solo las partes que no te convencen.
Así funciona más o menos SAVEPOINT en PostgreSQL. Te permite:
- Crear puntos de guardado dentro de una transacción — como marcadores en un libro.
- Volver a esos puntos para deshacer parte de las operaciones realizadas, sin tener que hacer rollback de toda la transacción.
- Seguir trabajando con los datos restantes, sin tener que empezar todo de nuevo.
Sintaxis básica de SAVEPOINT
Los comandos relacionados con SAVEPOINT son bastante sencillos. Aquí tienes lo básico:
Crear un punto de guardado (SAVEPOINT):
SAVEPOINT savepoint_name;
Es como decir: "Vamos a guardar este sitio, por si acaso luego queremos volver aquí."
Hacer rollback a un punto de guardado (ROLLBACK TO SAVEPOINT):
ROLLBACK TO SAVEPOINT savepoint_name;
Si algo sale mal, vuelves al SAVEPOINT indicado y deshaces todos los cambios hechos desde que lo creaste.
RELEASE SAVEPOINT):
RELEASE SAVEPOINT savepoint_name;
Esto libera el sitio donde estaba el "marcador". Después de esto, ya no podrás volver a ese punto.
Ejemplo sencillo: compra en una tienda online
Imagina que gestionamos una tienda online. Un cliente añade varios productos al carrito y queremos hacer una transacción que incluya el pedido y los cambios en el stock del almacén. Pero si una de las etapas falla, queremos deshacer solo una parte de la transacción, no todo.
BEGIN;
-- Paso 1: Reservar el producto "Libro SQL"
UPDATE inventory SET stock = stock - 1 WHERE product_id = 101;
-- Creamos un punto de guardado
SAVEPOINT libro_reservado;
-- Paso 2: Reservar el producto "Taza PostgreSQL"
UPDATE inventory SET stock = stock - 1 WHERE product_id = 102;
-- Ups, resulta que no hay tazas en el almacén!
ROLLBACK TO SAVEPOINT libro_reservado;
-- Confirmamos los cambios solo para el libro
COMMIT;
¿Qué pasa en este ejemplo?
- Empezamos la transacción con
BEGIN. - Después de reservar el libro, creamos el punto de guardado
libro_reservado. Es nuestro primer "checkpoint". - Intentamos reservar la taza, pero ocurre un error (por ejemplo, no hay stock suficiente).
- Hacemos rollback al punto
libro_reservadopara deshacer solo los cambios relacionados con la taza. - Finalmente, confirmamos los cambios del libro con
COMMIT.
Ejemplo más avanzado: procesamiento de datos en varias etapas
Ahora imagina que trabajas con un sistema de gestión de pedidos donde tienes que actualizar varias tablas: orders (pedidos), inventory (stock del almacén) y billing (facturación). Si algo falla en algún paso, no quieres perder el progreso en las otras tablas. Aquí es donde SAVEPOINT te salva.
BEGIN;
-- Paso 1: Crear un nuevo pedido
INSERT INTO orders (order_id, customer_id, status) VALUES (1, 123, 'pendiente');
SAVEPOINT despues_pedido_creado;
-- Paso 2: Actualizar el stock del almacén
UPDATE inventory SET stock = stock - 2 WHERE product_id = 101;
SAVEPOINT despues_stock_actualizado;
-- Paso 3: Realizar el pago
INSERT INTO billing (order_id, amount, status) VALUES (1, 100, 'pagado');
-- Ups, error: ¡tarjeta de crédito rechazada!
ROLLBACK TO SAVEPOINT despues_stock_actualizado;
-- Volvemos al paso después de actualizar el stock, pero el pedido sigue en estado "pendiente".
UPDATE orders SET status = 'fallido' WHERE order_id = 1;
COMMIT;
Fíjate cómo con SAVEPOINT dividimos la transacción en etapas lógicas y volvemos al punto necesario, manteniendo parte de los cambios.
Consejos útiles al trabajar con SAVEPOINT
- Usa nombres significativos para los puntos de guardado. En los ejemplos de arriba,
despues_pedido_creadoes mucho más claro que simplementepaso1. - Los puntos de guardado anidados funcionan bien: puedes crear un
SAVEPOINTincluso dentro de un rollback a otro punto. - Libera recursos eliminando los puntos que ya no necesitas con
RELEASE SAVEPOINT. Esto puede mejorar el rendimiento, sobre todo en transacciones grandes.
Escenarios reales de uso
Procesamiento de operaciones bancarias: Por ejemplo, al transferir dinero entre varias cuentas puedes volver a una etapa concreta si una de las transferencias falla.
Importar datos desde archivos: Si importas un archivo CSV grande, puedes revisar cada línea y hacer rollback solo de los datos erróneos, manteniendo los que sí se importaron bien.
Actualización masiva de registros: Si tienes un script SQL complejo para actualizar miles de filas, SAVEPOINT te permite volver a una etapa anterior si ocurre un error a mitad de ejecución.
Errores y trampas típicas
A veces usar SAVEPOINT puede dar resultados inesperados si no entiendes bien cómo funcionan. Por ejemplo:
- Si olvidas hacer rollback a un punto de guardado o eliminarlo, puedes crear situaciones donde los recursos quedan bloqueados hasta que termine la transacción.
SAVEPOINTno puede deshacer acciones que ocurrieron antes de crear el punto. Por ejemplo, los datos confirmados conCOMMITya no se pueden deshacer.
Ahora puedes experimentar con seguridad en tus transacciones, creando puntos de guardado donde lo necesites. Nos esperan más prácticas de SQL, así que prepárate para la próxima tanda de aventuras.
GO TO FULL VERSION