Contenido de esta guía
Qué es un SAVEPOINT
SAVEPOINT crea una marca con nombre dentro de una transacción. Si una operación posterior sale mal, puedes volver a esa marca sin descartar necesariamente todo lo que hiciste antes dentro de la misma transacción.
Es útil cuando una tarea tiene varias etapas y quieres conservar las primeras aunque tengas que repetir una etapa posterior. No sustituye a COMMIT: los cambios siguen pendientes hasta que la transacción completa se confirma.
El flujo: crear, probar, volver o liberar
- Abre una transacción.
- Realiza una primera parte válida.
- Crea un
SAVEPOINT. - Prueba la parte arriesgada.
- Si falla tu comprobación, usa
ROLLBACK TO SAVEPOINT nombre. - Cuando ya no necesites la marca, puedes liberarla con
RELEASE SAVEPOINT nombre.
Idea clave: volver a un savepoint no equivale a cerrar toda la transacción. El trabajo anterior a la marca sigue dentro de la transacción y todavía necesita un COMMIT o un ROLLBACK final.
Ejemplo: conservar una reserva y deshacer un descuento excesivo
El producto 2 empieza con 7 unidades. Reservamos 2, creamos una marca y después probamos una segunda reducción que decidimos deshacer.
BEGIN;
UPDATE productos
SET stock = stock - 2
WHERE id = 2;
SAVEPOINT reserva_validada;
UPDATE productos
SET stock = stock - 5
WHERE id = 2;
ROLLBACK TO SAVEPOINT reserva_validada;
SELECT stock AS stock_antes_de_commit
FROM productos
WHERE id = 2;
COMMIT;| stock_antes_de_commit |
|---|
| 5 |
La primera reducción queda pendiente; la segunda se revierte. Si finalmente ejecutas COMMIT, se conserva el stock 5.
ROLLBACK y ROLLBACK TO no resuelven lo mismo
| Sentencia | Efecto |
|---|---|
ROLLBACK | Abandona la transacción completa. |
ROLLBACK TO SAVEPOINT punto | Deshace el trabajo posterior a la marca y permite continuar. |
RELEASE SAVEPOINT punto | Elimina esa marca; no confirma por sí sola la transacción exterior. |
Error frecuente
Creer que RELEASE equivale siempre a COMMIT
En una transacción exterior, liberar un savepoint no vuelve permanentes los cambios por sí mismo. Si luego haces ROLLBACK de la transacción exterior, también se pierden los cambios que habían quedado después de RELEASE.
Comprueba lo aprendido
Protege una segunda modificación
Escribe una secuencia que reduzca en 1 el stock del producto 5, cree el savepoint primera_reserva, reduzca después otras 3 unidades y deshaga únicamente esa segunda reducción. Termina consultando el stock antes del COMMIT.
ROLLBACK TO SAVEPOINT, no un ROLLBACK total.Solución razonada
BEGIN;
UPDATE productos SET stock = stock - 1 WHERE id = 5;
SAVEPOINT primera_reserva;
UPDATE productos SET stock = stock - 3 WHERE id = 5;
ROLLBACK TO SAVEPOINT primera_reserva;
SELECT stock FROM productos WHERE id = 5;
COMMIT;El savepoint se coloca cuando el estado que quieres conservar ya es válido. Volver a él elimina únicamente la segunda reducción.
Compatibilidad
PostgreSQL, SQLite y MySQL disponen de savepoints, pero hay matices de sintaxis y de comportamiento en contextos específicos. SQLite permite savepoints anidados; PostgreSQL documenta SAVEPOINT, ROLLBACK TO SAVEPOINT y RELEASE SAVEPOINT como operaciones de la transacción actual. Comprueba también si tu framework crea savepoints automáticamente.
Qué debes recordar
- Un savepoint marca un estado intermedio dentro de una transacción.
ROLLBACK TOpermite repetir una parte sin abandonar necesariamente todo el trabajo.RELEASEelimina la marca, pero no sustituye al COMMIT exterior.- Usa nombres que indiquen qué estado ya ha sido validado.