SQL DML: INSERT, UPDATE, DELETE y Transacciones
SQL DML: INSERT, UPDATE, DELETE y Transacciones
Curso 2023/2024
Índice
2 La sentencia INSERT 2
2.1 Sintaxis de la sentencia INSERT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2.2 La sentencia INSERT y SELECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
3 La sentencia UPDATE 4
4 La sentencia DELETE 5
6 Transacciones 7
6.1 Definición . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
6.2 Propiedades ACID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
6.3 AUTOCOMMIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
6.4 START TRANSACTION, COMMIT y ROLLBACK . . . . . . . . . . . . . . . . . . . . . . . . . . 8
6.5 SAVEPOINT, ROLLBACK TO SAVEPOINT y RELEASE SAVEPOINT . . . . . . . . . . . . . 10
6.6 Acceso concurrente a los datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
6.6.1 Ejemplo de Dirty Read (Lectura sucia) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
6.6.2 Ejemplo de Non‑Repeatable Read (Lectura No Repetible) . . . . . . . . . . . . . . . . . 12
6.6.3 Ejemplo de Phantom Read (Lectura fantasma) . . . . . . . . . . . . . . . . . . . . . . . 12
6.7 Niveles de aislamiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
6.7.1 Ejemplo: Evaluación de los niveles de aislamiento ante el problema Dirty Read. . . . . . 13
6.7.2 Ejemplo: Evaluación de los niveles de aislamiento ante el problema Non‑Repeatable Read. 15
6.7.3 Ejemplo: Evaluación de los niveles de aislamiento ante el problema Phantom Read. . . 16
6.7.4 Ejemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
6.8 Cómo realizar transacciones con procedimientos almacenados . . . . . . . . . . . . . . . . . . 18
7 Ejercicios prácticos 20
7.1 Tienda de informática . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
7.2 Empleados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
7.3 Jardinería . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
9 Ejercicios de teoría 26
i
Unidad 11. Manipulación de datos. Curso 2023/2024
10 Referencias 27
11 Licencia 28
iii
Índice de cuadros
iv
1 Tratamiento de los datos
El DML (Data Manipulation Language) es la parte de SQL dedicada a la manipulación de los datos. Las sentencias
DML son las siguientes:
En este tema nos vamos a centrar en el uso de las sentencias INSERT, UPDATE y DELETE.
1
2 La sentencia INSERT
2
Unidad 11. Manipulación de datos. Curso 2023/2024
5 SELECT ...
6 [ON DUPLICATE KEY UPDATE assignment_list]
7
8 value:
9 {expr | DEFAULT}
10
11 assignment:
12 col_name = value
13
14 assignment_list:
15 assignment [, assignment] ...
4
4 La sentencia DELETE
5
5 Borrado y modificación de datos con integridad
referencial
• ON DELETE y ON UPDATE: Nos permiten indicar el efecto que provoca el borrado o la actualización
de los datos que están referenciados por claves ajenas. Las opciones que podemos especificar son las
siguientes:
– RESTRICT: Impide que se puedan actualizar o eliminar las filas que tienen valores referenciados
por claves ajenas. Es la opción por defecto en MySQL.
– CASCADE: Permite actualizar o eliminar las filas que tienen valores referenciados por claves ajenas.
– SET NULL: Asigna el valor NULL a las filas que tienen valores referenciados por claves ajenas.
– NO ACTION: Es una palabra clave del estándar SQL. En MySQL es equivalente a RESTRICT.
– SET DEFAULT: No es posible utilizar esta opción cuando trabajamos con el motor de almacena‑
miento InnoDB. Puedes encontrar más información en la documentación oficial de MySQL.
6
6 Transacciones
6.1 Definición
Una transacción SQL es un conjunto de sentencias SQL que se ejecutan formando una unidad lógica de trabajo
(LUW del inglés Logic Unit of Work), es decir, en forma indivisible o atómica.
Una transacción SQL finaliza con un COMMIT, para aceptar todos los cambios que la transacción ha realizado
en la base de datos, o un ROLLBACK para deshacerlos.
MySQL nos permite realizar transacciones en sus tablas si hacemos uso del motor de almacenamiento InnoDB
(MyISAM no permite el uso de transacciones).
El uso de transacciones nos permite realizar operaciones de forma segura y recuperar datos si se produce algún
fallo en el servidor durante la transacción, pero por otro lado las transacciones pueden aumentar el tiempo de
ejecución de las instrucciones.
Las propiedades ACID garantizan que las transacciones se puedan realizar en una base de datos de forma segu‑
ra. Decimos que un Sistema Gestor de Bases de Datos es ACID compliant cuando permite realizar transaccio‑
nes.
• Atomicidad: Esta propiedad quiere decir que una transacción es indivisible, o se ejecutan todas la sen‑
tencias o no se ejecuta ninguna.
• Consistencia: Esta propiedad asegura que después de una transacción la base de datos estará en un
estado válido y consistente.
• Aislamiento: Esta propiedad garantiza que cada transacción está aislada del resto de transacciones y que
el acceso a los datos se hará de forma exclusiva. Por ejemplo, si una transacción que quiere acceder de
forma concurrente a los datos que están siendo utilizados por otra transacción, no podrá hacerlo hasta
que la primera haya terminado.
• Durabilidad: Esta propiedad quiere decir que los cambios que realiza una transacción sobre la base de
datos son permanentes.
7
Unidad 11. Manipulación de datos. Curso 2023/2024
6.3 AUTOCOMMIT
Algunos Sistemas Gestores de Bases de Datos, como MySQL (si trabajamos con el motor InnoDB) tienen ac‑
tivada por defecto la variable AUTOCOMMIT. Esto quiere decir que automáticamente se aceptan todos los
cambios realizados después de la ejecución de una sentencia SQL y no es posible deshacerlos.
Aunque la variable AUTOCOMMIT está activada por defecto al inicio de una sesión SQL, podemos configurarlo
para indicar si queremos trabajar con transacciones implícitas o explícitas.
1 SELECT @@AUTOCOMMIT;
1 SET AUTOCOMMIT = 0;
Si hacemos esto siempre tendríamos una transacción abierta y los cambios sólo se aplicarían en la base de
datos ejecutando la sentencia COMMIT de forma explícita.
1 SET AUTOCOMMIT = 1;
Los pasos para realizar una transacción en MySQL son los siguientes:
1. Indicar que vamos a realizar una transacción con la sentencia START TRANSACTION, BEGIN o BEGIN
WORK.
2. Realizar las operaciones de manipulación de datos sobre la base datos (insertar, actualizar o borrar filas).
3. Si las operaciones se han realizado correctamente y queremos que los cambios se apliquen de forma per‑
manente sobre la base de datos usaremos la sentencia COMMIT. Sin embargo, si durante las operaciones
ocurre algún error y no queremos aplicar los cambios realizados podemos deshacerlos con la sentencia
ROLLBACK.
A continuación se muestra la sintaxis que aparece en la documentación oficial para realizar transacciones en
MySQL.
1 START TRANSACTION
2 [transaction_characteristic [, transaction_characteristic] ...]
3
4 transaction_characteristic: {
5 WITH CONSISTENT SNAPSHOT
6 | READ WRITE
7 | READ ONLY
8 }
9
10 BEGIN [WORK]
11 COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
12 ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
13 SET autocommit = {0 | 1}
Ejemplo 1:
1 START TRANSACTION;
2 SELECT @A:=SUM(salary) FROM table1 WHERE type=1;
3 UPDATE table2 SET summary=@A WHERE type=1;
4 COMMIT;
Ejemplo 2:
Ejemplo 3:
8 );
9
10 INSERT INTO cuentas VALUES (1, 1000);
11 INSERT INTO cuentas VALUES (2, 2000);
12 INSERT INTO cuentas VALUES (3, 0);
13
14 -- 1. Consultamos el estado actual de las cuentas
15 SELECT *
16 FROM cuentas;
17
18 -- 2. Suponga que queremos realizar una transferencia de dinero entre dos
cuentas bancarias con la siguiente transacción:
19 START TRANSACTION;
20 UPDATE cuentas SET saldo = saldo - 100 WHERE id = 1;
21 UPDATE cuentas SET saldo = saldo + 100 WHERE id = 2;
22 COMMIT;
23
24 -- 3. ?`Qué devolverá esta consulta?
25 SELECT *
26 FROM cuentas;
27
28 -- 4. Suponga que queremos realizar una transferencia de dinero entre dos
cuentas bancarias con la siguiente transacción y una de las dos cuentas no
existe:
29 START TRANSACTION;
30 UPDATE cuentas SET saldo = saldo - 100 WHERE id = 9999;
31 UPDATE cuentas SET saldo = saldo + 100 WHERE id = 2;
32 COMMIT;
33
34 -- 5. ?`Qué devolverá esta consulta?
35 SELECT *
36 FROM cuentas;
37
38 -- 6. Suponga que queremos realizar una transferencia de dinero entre dos
cuentas bancarias con la siguiente transacción y la cuenta origen no tiene
saldo:
39 START TRANSACTION;
40 UPDATE cuentas SET saldo = saldo - 100 WHERE id = 3;
41 UPDATE cuentas SET saldo = saldo + 100 WHERE id = 2;
42 COMMIT;
43
44 -- 7. ?`Qué devolverá esta consulta?
45 SELECT *
46 FROM cuentas;
Si trabajamos con tablas InnoDB en MySQL también es posible hacer uso de las sentencias: SAVEPOINT,
ROLLBACK TO SAVEPOINT y RELEASE SAVEPOINT.
identificador. Si en una transacción existen dos SAVEPOINT con el mismo nombre sólo se tendrá en
cuenta el último que se ha definido.
• ROLLBACK TO SAVEPOINT: Nos permite hacer un ROLLBACK deshaciendo sólo las instrucciones que
se hayan ejecutado hasta el SAVEPOINT que se indique.
• RELEASE SAVEPOINT: Elimina un SAVEPOINT.
A continuación se muestra la sintaxis que aparece en la documentación oficial para crear SAVEPOINT.
1 SAVEPOINT identifier
2 ROLLBACK [WORK] TO [SAVEPOINT] identifier
3 RELEASE SAVEPOINT identifier
Ejemplo:
Cuando dos transacciones distintas intentan acceder concurrentemente a los mismos datos pueden ocurrir los
siguientes problemas:
• Dirty Read (Lectura sucia). Sucede cuando una segunda transacción lee datos que están siendo modifi‑
cados por una transacción antes de que haga COMMIT.
• Non‑Repeatable Read (Lectura No Repetible). Se produce cuando una transacción consulta el mismo
dato dos veces durante la ejecución de la transacción y la segunda vez encuentra que el valor del dato
ha sido modificado por otra transacción.
• Phantom Read (Lectura fantasma). Este error ocurre cuando una transacción ejecuta dos veces una
consulta que devuelve un conjunto de filas y en la segunda ejecución de la consulta aparecen nuevas
filas en el conjunto que no existían cuando se inició lo transacción.
Ejemplos
Transacción 1 Transacción 2
Transacción 1 Transacción 2
Transacción 1 Transacción 2
Para evitar que sucedan los problemas de acceso concurrente que hemos comentado en el punto anterior po‑
demos establecer diferentes niveles de aislamiento que controlan el nivel de bloqueo durante el acceso a los
• Read Uncommitted. En este nivel no se realiza ningún bloqueo, por lo tanto, permite que sucedan los
tres problemas
• Read Committed. En este caso los datos leídos por una transacción pueden ser modificados por otras
transacciones, por lo tanto, se pueden dar los problemas Non‑Repeteable Read y Phantom Read.
• Repeatable Read. En este nivel ningún registro leído con un SELECT puede ser modificado en otra tran‑
sacción, por lo tanto, sólo puede suceder el problema del Phantom Read.
• Serializable. En este caso las transacciones se ejecutan unas detrás de otras, sin que exista la posibilidad
de concurrencia.
La siguiente tabla muestra los problemas de lectura que pueden ocurrir en cada uno de los modos de aisla‑
miento.
Podemos consultar el nivel de aislamiento que estamos utilizando, consultando el contenido de la variable
global y de sesión @@transaction_isolation.
1 -- Variable global
2 SELECT @@GLOBAL.transaction_isolation;
1 -- Variable de sesión
2 SELECT @@SESSION.transaction_isolation;
También podemos consultar el contenido de la variable de sesión sin utilizar la palabra reservada SESSION.
1 SELECT @@transaction_isolation;
6.7.1 Ejemplo: Evaluación de los niveles de aislamiento ante el problema Dirty Read.
En este ejemplo vamos a simular que hay dos usuarios que quieren acceder de forma concurrente a los mismos
datos de una tabla. Para simular los dos usuarios vamos a iniciar dos terminales para conectarnos a un servidor
MySQL. Desde el terminal A vamos a ejecutar las siguientes sentencias SQL:
3 USE test;
4
5 CREATE TABLE cuentas (
6 id INTEGER UNSIGNED PRIMARY KEY,
7 saldo DECIMAL(11,2) CHECK (saldo >= 0)
8 );
9
10 INSERT INTO cuentas VALUES (1, 1000);
11 INSERT INTO cuentas VALUES (2, 2000);
12 INSERT INTO cuentas VALUES (3, 0);
13
14 -- 1. Configuramos que en esta sesión vamos a utilizar el nivel de aislamiento
READ UNCOMMITTED
15 SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
16 -- SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
17 -- SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
18 -- SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
19
20
21 -- 2. Ejecutamos una transacción para transfereir dinero entre dos cuentas
22 START TRANSACTION;
23 UPDATE cuentas SET saldo = saldo - 100 WHERE id = 1;
NOTA: Observe que la transacción que estamos ejecutando en el terminal A todavía no ha finalizado, porque
no hemos ejecutado COMMIT ni ROLLBACK.
Ahora desde el terminal B ejecute las siguientes sentencias SQL:
Ahora ejecute ROLLBACK en el terminal A para finalizar la transacción que estaba sin finalizar.
¿Qué es lo que ha sucedido? Repita el ejercicio utilizando los otros niveles de aislamiento (READ COMMITTED,
REPEATABLE READ y SERIALIZABLE). Tendrá que configurar el nivel de aislamiento que va a utilizar du‑
rante la sesión con las siguientes sentencias:
En este ejemplo vamos a simular que hay dos usuarios que quieren acceder de forma concurrente a los mismos
datos de una tabla. Para simular los dos usuarios vamos a iniciar dos terminales para conectarnos a un servidor
MySQL. Desde el terminal A vamos a ejecutar las siguientes sentencias SQL:
NOTA: Observe que la transacción que estamos ejectando en el terminal A todavía no ha finalizado, porque no
hemos ejecutado COMMIT ni ROLLBACK.
Ahora volvemos a ejecutar en el terminal A la misma consulta que ejecutamos al inicio de la transacción.
¿Qué es lo que ha sucedido? Repita el ejercicio utilizando los otros niveles de aislamiento (READ COMMITTED,
REPEATABLE READ y SERIALIZABLE). Tendrá que configurar el nivel de aislamiento que va a utilizar du‑
rante la sesión con las siguientes sentencias:
En este ejemplo vamos a simular que hay dos usuarios que quieren acceder de forma concurrente a los mismos
datos de una tabla. Para simular los dos usuarios vamos a iniciar dos terminales para conectarnos a un servidor
MySQL. Desde el terminal A vamos a ejecutar las siguientes sentencias SQL:
NOTA: Observe que la transacción que estamos ejectando en el terminal A todavía no ha finalizado, porque no
hemos ejecutado COMMIT ni ROLLBACK.
Ahora volvemos a ejecutar en el terminal A la misma consulta que ejecutamos al inicio de la transacción.
¿Qué es lo que ha sucedido? Repita el ejercicio utilizando los otros niveles de aislamiento (READ COMMITTED,
REPEATABLE READ y SERIALIZABLE). Tendrá que configurar el nivel de aislamiento que va a utilizar du‑
rante la sesión con las siguientes sentencias:
Cuando una transacción accede a los datos lo hace de forma exclusiva, de modo que una transacción no podrá
acceder a los datos que están siendo utilizados por una transacción hasta que ésta haya terminado.
• Base de datos.
• Tabla.
• Fila.
• Columna.
6.7.4 Ejemplo
En este ejemplo vamos a simular que hay dos usuarios que quieren acceder de forma concurrente a los mismos
datos de una tabla. Para simular los dos usuarios vamos a iniciar dos terminales para conectarnos a un servidor
NOTA: Observe que la transacción no que estamos ejectando en el terminal A todavía no ha finalizado, porque
no hemos ejecutado COMMIT ni ROLLBACK.
¿Qué es lo que ha ocurrido en el terminal B? ¿Puedo acceder a los datos para consultaros? ¿Y para modificarlos?
¿Puedo modificar desde el terminal B una cuenta bancaria que no esté siendo utilizada por la transacción del
terminal A?
Ahora ejecute COMMIT en el terminal A para finalizar la transacción que estaba sin finalizar. ¿Qué es lo que ha
sucedido?
Podemos utilizar el manejo de errores para decidir si hacemos ROLLBACK de una transacción. En el siguiente
ejemplo vamos a capturar los errores que se produzcan de tipo SQLEXCEPTION y SQLWARNING.
Ejemplo:
1 DELIMITER $$
2 CREATE PROCEDURE transaccion_en_mysql()
3 BEGIN
4 DECLARE EXIT HANDLER FOR SQLEXCEPTION
5 BEGIN
6 -- ERROR
7 ROLLBACK;
8 END;
9
10 DECLARE EXIT HANDLER FOR SQLWARNING
11 BEGIN
12 -- WARNING
13 ROLLBACK;
14 END;
15
16 START TRANSACTION;
17 -- Sentencias SQL
18 COMMIT;
19 END
20 $$
En lugar de tener un manejador para cada tipo de error, podemos tener uno común para todos los casos.
1 DELIMITER $$
2 CREATE PROCEDURE transaccion_en_mysql()
3 BEGIN
4 DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
5 BEGIN
6 -- ERROR, WARNING
7 ROLLBACK;
8 END;
9
10 START TRANSACTION;
11 -- Sentencias SQL
12 COMMIT;
13 END
14 $$
3. Inserta un nuevo producto asociado a uno de los nuevos fabricantes. La sentencia de inserción debe
incluir: código, nombre, precio y código_fabricante.
4. Inserta un nuevo producto asociado a uno de los nuevos fabricantes. La sentencia de inserción debe
incluir: nombre, precio y código_fabricante.
5. Crea una nueva tabla con el nombre fabricante_productos que tenga las siguientes columnas:
nombre_fabricante, nombre_producto y precio. Una vez creada la tabla inserta todos los re‑
gistros de la base de datos tienda en esta tabla haciendo uso de única operación de inserción.
6. Crea una vista con el nombre vista_fabricante_productosque tenga las siguientes columnas:
nombre_fabricante, nombre_producto y precio.
7. Elimina el fabricante Asus. ¿Es posible eliminarlo? Si no fuese posible, ¿qué cambios debería realizar
para que fuese posible borrarlo?
8. Elimina el fabricante Xiaomi. ¿Es posible eliminarlo? Si no fuese posible, ¿qué cambios debería realizar
para que fuese posible borrarlo?
9. Actualiza el código del fabricante Lenovo y asígnale el valor 20. ¿Es posible actualizarlo? Si no fuese
posible, ¿qué cambios debería realizar para que fuese actualizarlo?
10. Actualiza el código del fabricante Huawei y asígnale el valor 30. ¿Es posible actualizarlo? Si no fuese
posible, ¿qué cambios debería realizar para que fuese actualizarlo?
12. Elimina todas las impresoras que tienen un precio menor de 200 €.
7.2 Empleados
20
Unidad 11. Manipulación de datos. Curso 2023/2024
4. Inserta un nuevo empleado asociado a uno de los nuevos departamentos. La sentencia de inserción debe
incluir: código, nif, nombre, apellido1, apellido2 y codigo_departamento.
5. Inserta un nuevo empleado asociado a uno de los nuevos departamentos. La sentencia de inserción debe
incluir: nif, nombre, apellido1, apellido2 y codigo_departamento.
6. Crea una nueva tabla con el nombre departamento_backup que tenga las mismas columnas
que la tabla departamento. Una vez creada copia todos las filas de tabla departamento en
departamento_backup.
7. Elimina el departamento Proyectos. ¿Es posible eliminarlo? Si no fuese posible, ¿qué cambios debería
realizar para que fuese posible borrarlo?
8. Elimina el departamento Desarrollo. ¿Es posible eliminarlo? Si no fuese posible, ¿qué cambios debe‑
ría realizar para que fuese posible borrarlo?
9. Actualiza el código del departamento Recursos Humanos y asígnale el valor 30. ¿Es posible actuali‑
zarlo? Si no fuese posible, ¿qué cambios debería realizar para que fuese actualizarlo?
10. Actualiza el código del departamento Publicidad y asígnale el valor 40. ¿Es posible actualizarlo? Si no
fuese posible, ¿qué cambios debería realizar para que fuese actualizarlo?
11. Actualiza el presupuesto de los departamentos sumándole 50000 € al valor del presupuesto actual, sola‑
mente a aquellos departamentos que tienen un presupuesto menor que 20000 €.
12. Realiza una transacción que elimine todas los empleados que no tienen un departamento asociado.
7.3 Jardinería
3. Inserta un cliente que tenga como representante de ventas el empleado que hemos creado en el paso
anterior.
4. Inserte un pedido para el cliente que acabamos de crear, que contenga al menos dos productos diferen‑
tes.
5. Actualiza el código del cliente que hemos creado en el paso anterior y averigua si hubo cambios en las
tablas relacionadas.
10. Establece a 0 el límite de crédito del cliente que menos unidades pedidas tenga del producto 11679.
11. Modifica la tabla detalle_pedido para insertar un campo numérico llamado iva. Mediante una tran‑
sacción, establece el valor de ese campo a 18 para aquellos registros cuyo pedido tenga fecha a partir de
Enero de 2009. A continuación actualiza el resto de pedidos estableciendo el iva al 21.
12. Modifica la tabla detalle_pedido para incorporar un campo numérico llamado total_linea y ac‑
tualiza todos sus registros para calcular su valor con la fórmula:
13. Borra el cliente que menor límite de crédito tenga. ¿Es posible borrarlo solo con una consulta? ¿Por qué?
14. Inserta una oficina con sede en Granada y tres empleados que sean representantes de ventas.
15. Inserta tres clientes que tengan como representantes de ventas los empleados que hemos creado en el
paso anterior.
16. Realiza una transacción que inserte un pedido para cada uno de los clientes. Cada pedido debe incluir
dos productos.
17. Borra uno de los clientes y comprueba si hubo cambios en las tablas relacionadas. Si no hubo cambios,
modifica las tablas necesarias estableciendo la clave foránea con la cláusula ON DELETE CASCADE.
18. Realiza una transacción que realice los pagos de los pedidos que han realizado los clientes del ejercicio
anterior.
1. Ejecuta las siguientes instrucciones y resuelve las cuestiones que se plantean en cada paso.
1 SET AUTOCOMMIT = 0;
2 SELECT @@AUTOCOMMIT;
3
4 DROP DATABASE IF EXISTS test;
5 CREATE DATABASE test CHARACTER SET utf8mb4;
6 USE test;
7
8 CREATE TABLE producto (
9 id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
10 nombre VARCHAR(100) NOT NULL,
11 precio DOUBLE
12 );
13
14 INSERT INTO producto (id, nombre) VALUES (1, 'Primero');
15 INSERT INTO producto (id, nombre) VALUES (2, 'Segundo');
16 INSERT INTO producto (id, nombre) VALUES (3, 'Tercero');
17
18
19 -- 1. Comprueba que las filas se han insertado en la tabla de forma correcta.
20 SELECT *
21 FROM producto;
Ahora vamos a simular que perdemos la conexión con el servidor antes de que la transacción sea completa‑
da (Observa que hemos ejecutado SET AUTOCOMMIT = 0). Para simular que perdemos la conexión desde
MySQL Workbench hay que cerrar la pestaña de conexión con el servidor. Si estás conectado al servidor desde
la consola de MySQL sólo tienes que ejecutar el comando EXIT.
1 USE test;
2
3 -- ?`Qué devolverá esta consulta?
4 SELECT *
5 FROM producto;
2. Ejecuta las siguientes instrucciones y resuelve las cuestiones que se plantean en cada paso.
1 SET AUTOCOMMIT = 1;
2 SELECT @@AUTOCOMMIT;
3
4 DROP DATABASE IF EXISTS test;
5 CREATE DATABASE test CHARACTER SET utf8mb4;
6 USE test;
23
Unidad 11. Manipulación de datos. Curso 2023/2024
7
8 CREATE TABLE producto (
9 id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
10 nombre VARCHAR(100) NOT NULL,
11 precio DOUBLE
12 );
13
14 INSERT INTO producto (id, nombre) VALUES (1, 'Primero');
15 INSERT INTO producto (id, nombre) VALUES (2, 'Segundo');
16 INSERT INTO producto (id, nombre) VALUES (3, 'Tercero');
17
18
19 -- 1. ?`Qué devolverá esta consulta?
20 SELECT *
21 FROM producto;
22
23 -- 2. Vamos a intentar deshacer la transacción actual
24 ROLLBACK;
25
26 -- 3. ?`Qué devolverá esta consulta? Justifique su respuesta.
27 SELECT *
28 FROM producto;
29
30 -- 4. Ejecutamos la siguiente transacción
31 START TRANSACTION;
32 INSERT INTO producto (id, nombre) VALUES (4, 'Cuarto');
33 SELECT * FROM producto;
34 ROLLBACK;
35
36 -- 5. ?`Qué devolverá esta consulta? Justifique su respuesta.
37 SELECT * FROM producto;
38
39 -- 6. Ejecutamos la siguiente transacción
40 INSERT INTO producto (id, nombre) VALUES (5, 'Quinto');
41 ROLLBACK;
42
43 -- 7. ?`Qué devolverá esta consulta? Justifique su respuesta.
44 SELECT * FROM producto;
45
46 -- 8. Desactivamos el modo AUTOCOMMIT y borramos el contenido de la tabla
47 SET AUTOCOMMIT = 0;
48 SELECT @@AUTOCOMMIT;
49
50 DELETE FROM producto WHERE id > 0;
51
52 -- 9. Comprobamos que la tabla esta vacia
53 SELECT * FROM producto;
54
55 -- 10. Insertamos dos filas nuevas
56 INSERT INTO producto (id, nombre) VALUES (6, 'Sexto');
57 INSERT INTO producto (id, nombre) VALUES (7, 'Séptimo');
58 SELECT * FROM producto;
59
60 -- 11. Hacemos un ROLLBACK
61 ROLLBACK;
62
63 -- 12. ?`Qué devolverá esta consulta? Justifique su respuesta.
2. ¿Cuáles son los tres problemas de concurrencia en el acceso a datos que pueden suceder cuando se rea‑
lizan transacciones? Ponga un ejemplo para cada uno de ellos.
3. Cuando se trabaja con transacciones, el SGBD puede bloquear conjuntos de datos para evitar o permitir
que sucedan los problemas de concurrencia comentados en el ejercicio anterior. ¿Cuáles son los cuatro
niveles de aislamiento que se pueden solicitar al SGBD?
4. ¿Cuál es el nivel de aislamiento que se usa por defecto en las tablas InnoDB de MySQL?
7. Considera que tenemos una tabla donde almacenamos información sobre cuentas bancarias definida de
la siguiente manera:
Suponga que queremos realizar una transferencia de dinero entre dos cuentas bancarias con la siguiente tran‑
sacción:
1 START TRANSACTION;
2 UPDATE cuentas SET saldo = saldo - 100 WHERE id = 20;
3 UPDATE cuentas SET saldo = saldo + 100 WHERE id = 30;
4 COMMIT;
• ¿Qué ocurriría si el sistema falla o si se pierde la conexión entre el cliente y el servidor después de realizar
la primera sentencia UPDATE?
• ¿Qué ocurriría si no existiese alguna de las dos cuentas (id = 20 y id = 30)?
• ¿Qué ocurriría en el caso de que la primera sentencia UPDATE falle porque hay menos de 100 € en la
cuenta y no se cumpla la restricción del CHECK establecida en la tabla?
26
10 Referencias
• Bases de Datos. 2ª Edición. Grupo editorial Garceta. Iván López Montalbán, Manuel de Castro Vázquez y
John Ospino Rivas.
• Gestión de Bases de Datos. 2ª Edición. Ra‑Ma. Luis Hueso Ibáñez.
• SQL Transactions. Martti Laiho, Dimitris A. Dervos, Kari Silpiö. DBTech VET Teachers project.
• Transacción (informática). Wikipedia.
• ACID. Wikipedia.
• Aislamiento (ACID). Wikipedia.
• Materiales de la Familia Profesional Informática y Comunicaciones de la Junta de Andalucía.
• Vídeo. Cómo no vender la misma entrada a dos personas diferentes. José Muñoz. T3chFest 2023.
• Designing Data‑Intensive Applications. (Chapter 7. Transactions). O’Reilly. Martin Kleppmann.
27
11 Licencia
Esta página forma parte del curso Bases de Datos de José Juan Sánchez Hernández y su contenido se distribuye
bajo una licencia Creative Commons Reconocimiento‑NoComercial‑CompartirIgual 4.0 Internacional.
28