Manejo de Transacciones en SQLite

SQLiteSQLiteBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, exploraremos el manejo de transacciones de SQLite, centrándonos en mantener la integridad de los datos mediante el uso de transacciones. Aprenderemos cómo iniciar y confirmar (commit) transacciones, asegurando que múltiples operaciones relacionadas se traten como una sola unidad atómica.

Este laboratorio lo guiará a través del proceso de iniciar una transacción usando BEGIN TRANSACTION, realizar cambios en la base de datos y luego guardar permanentemente esos cambios usando la declaración COMMIT. También aprenderá cómo deshacer cambios usando ROLLBACK y usar SAVEPOINT para un control más granular. Esta experiencia práctica solidificará su comprensión de cómo las transacciones garantizan la atomicidad, consistencia, aislamiento y durabilidad (propiedades ACID) en SQLite.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL sqlite(("SQLite")) -.-> sqlite/SQLiteGroup(["SQLite"]) sqlite/SQLiteGroup -.-> sqlite/get_all("Select All Rows") sqlite/SQLiteGroup -.-> sqlite/query_where("Filter With WHERE") sqlite/SQLiteGroup -.-> sqlite/start_trans("Begin New Transaction") sqlite/SQLiteGroup -.-> sqlite/save_trans("Commit Transaction") sqlite/SQLiteGroup -.-> sqlite/undo_trans("Rollback Transaction") subgraph Lab Skills sqlite/get_all -.-> lab-552558{{"Manejo de Transacciones en SQLite"}} sqlite/query_where -.-> lab-552558{{"Manejo de Transacciones en SQLite"}} sqlite/start_trans -.-> lab-552558{{"Manejo de Transacciones en SQLite"}} sqlite/save_trans -.-> lab-552558{{"Manejo de Transacciones en SQLite"}} sqlite/undo_trans -.-> lab-552558{{"Manejo de Transacciones en SQLite"}} end

Crear una Base de Datos y una Tabla

En este primer paso, crearemos una base de datos SQLite y una tabla para almacenar datos de usuario. Esto proporcionará la base para explorar el manejo de transacciones en los pasos siguientes.

Primero, abra su terminal en la VM de LabEx. Su ruta predeterminada es /home/labex/project.

Ahora, creemos una base de datos SQLite llamada mydatabase.db. Ejecute el siguiente comando para crear el archivo de la base de datos y abrir la herramienta de línea de comandos de SQLite:

sqlite3 mydatabase.db

Verá un indicador que indica que ahora está dentro del shell de SQLite:

SQLite version 3.x.x
Enter ".help" for usage hints.
sqlite>

A continuación, cree una tabla llamada users para almacenar información básica del usuario. Esta tabla tendrá tres columnas: id (un identificador único), name y balance. Ingrese el siguiente comando SQL en el prompt sqlite> y presione Enter:

CREATE TABLE users (
    id INTEGER PRIMARY KEY,
    name TEXT,
    balance REAL
);

Este comando configura la tabla users donde:

  • id es un entero que sirve como clave primaria (primary key) para cada usuario.
  • name es un campo de texto que representa el nombre del usuario.
  • balance es un número real que representa el saldo de la cuenta del usuario.

Ahora, inserte algunos datos iniciales en la tabla users:

INSERT INTO users (name, balance) VALUES ('Alice', 100.0);
INSERT INTO users (name, balance) VALUES ('Bob', 200.0);

Estos comandos agregan dos usuarios, Alice y Bob, con saldos iniciales de 100.0 y 200.0, respectivamente.

Para confirmar que los datos se agregaron correctamente, ejecute este comando para ver todos los registros en la tabla:

SELECT * FROM users;

Resultado Esperado:

1|Alice|100.0
2|Bob|200.0

Este resultado muestra el id, name y balance para cada registro. El comando SELECT * recupera todas las columnas de la tabla especificada.

Iniciar y Confirmar (Commit) una Transacción

En este paso, aprenderá cómo iniciar y confirmar (commit) una transacción. Las transacciones son esenciales para garantizar la integridad de los datos al realizar múltiples operaciones relacionadas.

Para iniciar una transacción, use el comando BEGIN TRANSACTION:

BEGIN TRANSACTION;

Este comando le dice a SQLite que comience a rastrear los cambios, pero que no los aplique permanentemente a la base de datos hasta que confirme (commit) explícitamente la transacción.

Ahora, transfiramos 50.0 de Alice a Bob:

UPDATE users SET balance = balance - 50.0 WHERE name = 'Alice';
UPDATE users SET balance = balance + 50.0 WHERE name = 'Bob';

Estos comandos actualizan los saldos de Alice y Bob dentro de la transacción. El saldo de Alice se reduce en 50.0 y el saldo de Bob aumenta en 50.0.

Para guardar los cambios, use el comando COMMIT:

COMMIT;

Este comando confirma (commit) la transacción, haciendo que los cambios sean permanentes.

Verifique los cambios consultando la tabla nuevamente:

SELECT * FROM users;

Resultado Esperado:

1|Alice|50.0
2|Bob|250.0

Este resultado confirma que la transacción se confirmó (committed) con éxito y que los saldos de Alice y Bob se han actualizado en consecuencia.

Revertir (Rollback) una Transacción

En este paso, aprenderá cómo usar el comando ROLLBACK para deshacer los cambios realizados durante una transacción. Esto es esencial para manejar errores y garantizar la integridad de los datos.

Primero, inicie una nueva transacción:

BEGIN TRANSACTION;

Ahora, intentemos transferir 100.0 de Alice a Bob, pero esta vez, simularemos una condición de error:

UPDATE users SET balance = balance - 100.0 WHERE name = 'Alice';
UPDATE users SET balance = balance + 100.0 WHERE name = 'Bob';

Dado que Alice solo tiene 50.0, la primera actualización resultará en un saldo negativo. Si bien SQLite no aplica restricciones de forma predeterminada, simularemos que ocurre un error después de esta operación.

Para deshacer los cambios, use el comando ROLLBACK:

ROLLBACK;

Este comando revierte (rollback) la transacción, deshaciendo cualquier cambio realizado desde la declaración BEGIN TRANSACTION.

Verifique que los cambios se hayan revertido consultando la tabla users:

SELECT * FROM users;

Resultado Esperado:

1|Alice|50.0
2|Bob|250.0

Este resultado confirma que la transacción se revirtió (rolled back) con éxito y que los saldos de Alice y Bob permanecen sin cambios.

Implementar Puntos de Guardado (Savepoints)

En este paso, aprenderá cómo usar puntos de guardado (savepoints) dentro de las transacciones. Los puntos de guardado le permiten crear puntos intermedios dentro de una transacción a los que puede revertir (rollback), sin revertir toda la transacción.

Primero, inicie una nueva transacción:

BEGIN TRANSACTION;

Cree un punto de guardado (savepoint) llamado savepoint1:

SAVEPOINT savepoint1;

Ahora, transfiramos 20.0 de Alice a Bob:

UPDATE users SET balance = balance - 20.0 WHERE name = 'Alice';
UPDATE users SET balance = balance + 20.0 WHERE name = 'Bob';

Cree otro punto de guardado (savepoint) llamado savepoint2:

SAVEPOINT savepoint2;

Agreguemos un nuevo usuario llamado 'Charlie' con un saldo inicial de 300.0:

INSERT INTO users (name, balance) VALUES ('Charlie', 300.0);

Ahora, digamos que decidimos que agregar a Charlie fue un error. Podemos revertir (rollback) a savepoint1, lo que deshará la declaración INSERT y la transferencia de 20.0 entre Alice y Bob:

ROLLBACK TO SAVEPOINT savepoint1;

Verifique los cambios después de revertir (rollback) a savepoint1:

SELECT * FROM users;

Resultado Esperado:

1|Alice|50.0
2|Bob|250.0

Debería ver que Charlie no está en la tabla, y los saldos de Alice y Bob han vuelto a sus valores anteriores a savepoint1.

Ahora, transfiramos 10.0 de Alice a Bob:

UPDATE users SET balance = balance - 10.0 WHERE name = 'Alice';
UPDATE users SET balance = balance + 10.0 WHERE name = 'Bob';

Finalmente, confirme (commit) la transacción:

COMMIT;

Agregar una Restricción (Constraint) para Prevenir Saldos Negativos

En este paso, agregará una restricción (constraint) a la tabla users para evitar saldos negativos. Esto ayudará a garantizar la integridad de los datos al prevenir transacciones no válidas.

Agregue la siguiente restricción (constraint) a la tabla users:

ALTER TABLE users ADD CONSTRAINT positive_balance CHECK (balance >= 0);

Este comando agrega una restricción CHECK llamada positive_balance a la tabla users. Esta restricción asegura que la columna balance siempre debe ser mayor o igual a 0.

Ahora, intentemos transferir 1000 de Alice a Bob, lo que violará la restricción:

BEGIN TRANSACTION;
UPDATE users SET balance = balance - 1000 WHERE name = 'Alice';
UPDATE users SET balance = balance + 1000 WHERE name = 'Bob';

Esta vez, la declaración UPDATE lanzará un error porque viola la restricción positive_balance. Verá un mensaje de error como: Error: CHECK constraint failed: positive_balance.

Revierta (rollback) la transacción:

ROLLBACK;

Verifique que los cambios se hayan revertido (rolled back):

SELECT * FROM users;

Resultado Esperado:

1|Alice|40.0
2|Bob|260.0

Esto confirma que el ROLLBACK revirtió con éxito la base de datos a su estado original antes de la transacción fallida.

Resumen

En este laboratorio, ha aprendido los fundamentos del manejo de transacciones en SQLite. Ha cubierto cómo iniciar y confirmar (commit) transacciones, revertir (rollback) cambios, implementar puntos de guardado (savepoints) para un control más granular y agregar restricciones (constraints) para garantizar la integridad de los datos. Estas habilidades son cruciales para construir aplicaciones de bases de datos robustas y confiables.