BEGIN, COMMIT, ROLLBACK
En resumen: BEGIN inicia una transacción, COMMIT guarda sus cambios, ROLLBACK los deshace, y SAVEPOINT marca un punto hasta el que ROLLBACK TO puede deshacer.
Problema
El error después del cual nada está terminado
El programa sube un 10 % los precios de los lácteos y, en la misma transacción, corrige el precio del pan. La segunda consulta tiene un error: el precio queda negativo. Ejecútala:
La segunda consulta se detuvo. ¿Y la primera? ¿Se deshizo la subida de los lácteos, o entró?
La idea
La transacción se queda abierta
Ninguna de las dos. SQLite deshace solo la consulta que falla. La transacción se queda abierta, y la subida de los lácteos está en ella, todavía sin confirmar.
Pruébalo en el mismo campo, sin «Base nueva». Borra el texto, escribe SELECT name, price FROM products WHERE category_id = 4; y ejecútalo: los precios han subido. Luego escribe ROLLBACK; y ejecuta otra vez la consulta de precios.
Por eso un programa que trabaja con transacciones siempre tiene dos caminos: todo va bien, así que COMMIT; algo falló, así que ROLLBACK. Si no dice nada, la transacción se queda colgada. Mientras está colgada, en SQLite nadie más puede escribir en la base de datos, y en PostgreSQL y MySQL espera todo el que quiera cambiar las mismas filas.
Más precisamente, para curiosos
Si en este campo ejecutas BEGIN otra vez sin cerrar la transacción anterior, SQLite dice «cannot start a transaction within a transaction». PostgreSQL es más estricto: después de un error toda la transacción queda rota, y hasta el ROLLBACK cualquier consulta siguiente se niega a ejecutarse.
Míralo
Lo que veo por dentro
Dentro de la transacción los cambios se ven antes de confirmarse, pero solo para ella:
Otra conexión a la base de datos (otro usuario, otro programa) todavía ve los precios antiguos. Veremos las dos sesiones una al lado de la otra en la lección siguiente.
La idea
SAVEPOINT: volver a un punto
A veces quieres renunciar solo a una parte de la transacción. SAVEPOINT nombre fija un punto, y ROLLBACK TO nombre vuelve a él. Todo lo anterior al punto se queda, y la transacción continúa.
Una entrega: el pan ha llegado (+10), las bebidas no. Se suman por costumbre y luego se retiran:
Del pan hay 10 más, las bebidas no han cambiado.
Ejercicio
Solo sube el pan
La transacción sube un 5 % los precios del pan y de los lácteos. La gerencia dice que los lácteos mantienen los precios antiguos. Añade una línea para que solo se deshaga la subida de los lácteos.
Solución
BEGIN;
UPDATE products SET price = ROUND(price * 1.05, 2) WHERE category_id = 3;
SAVEPOINT dairy;
UPDATE products SET price = ROUND(price * 1.05, 2) WHERE category_id = 4;
ROLLBACK TO dairy;
COMMIT;
SELECT name, price FROM products WHERE category_id IN (3, 4);ROLLBACK TO dairy; en lugar del comentario. El pan está más caro, los lácteos tienen los precios antiguos, y la transacción termina con COMMIT.
Test
Ponte a prueba
Lecciones relacionadas
Sección «Lecciones relacionadas»- Se basa en: Aritmética en una consulta · UPDATE: cambiar valores · ACID: todo o nada
- Continúa en: Transacciones simultáneas · Migraciones del esquema · OLTP y OLAP · Cómo elegir una base de datos
- Ejercicios sobre el tema: Transacciones