TRANSACCIONALIDAD
Y
CONCURRENCIA
Bases de datos multiusuario
• Un SGBD permite el acceso simultáneo de varios
clientes.
• Si cada uno accede a diferentes tablas, no hay
ningún problema
• Si acceden a la misma tabla, pueden surgir
problemas
– Un cliente cambia una fila mientras otro la está
leyendo.
– Dos clientes intentan modificar la misma fila.
• Para evitar estos problemas los SGBD usan los
bloqueos.
Bloqueo
• Mecanismo utilizado por el servidor para evitar
los problemas derivados del uso simultáneo de
los datos.
• Se coloca un bloqueo en los datos en nombre de
un cliente para restringir el acceso por otros
clientes a estos datos hasta que el bloqueo ha
sido liberado.
• El bloqueo permite acceder a los datos por parte
del cliente que solicita el bloqueo, pero impone
ciertos límites a los otros clientes que quieren
acceder a dichos datos.
¿Lectura o escritura?
• No todos los tipos de acceso simultáneo
producen conflictos:
– Si un cliente quiere leer los datos, otros clientes que
quieren leer los mismos datos no producen un
conflicto, y todos ellos pueden leer al mismo tiempo.
Sin embargo, otro cliente que quiera escribir
(modificar) los datos deberá esperar hasta que la
lectura haya terminado.
– Si un cliente desea escribir datos, todos los demás
clientes tienen que esperar hasta que la escritura ha
terminado, independientemente de si los clientes
quieren leer o escribir.
Implícito o explícito
• Un bloqueo de los datos se puede adquirir de
forma implícita o explícita:
– El servidor realiza bloqueos implícitamente cuando el
cliente no hace nada especial para adquirirlos . Por
ejemplo, el servidor adquiere un bloqueo de lectura
cuando el cliente emite una sentencia SELECT y un
bloqueo de escritura cuando el cliente emite una
sentencia INSERT.
– Si el bloqueo implícito es insuficiente para los
propósitos de un cliente, podemos gestionarlos
explícitamente, adquiriéndolos con LOCK TABLES y
liberarlos con UNLOCK TABLES.
Nivel de detalle del bloqueo
• Bloqueos a nivel de tabla
– Evita que varios usuarios modifiquen los datos de una misma tabla de forma
simultánea.
– Provoca grandes periodos de espera al incrementarse el número de usuarios.
– Utilizado por MySQL cuando solicitamos un bloqueo explícito (con LOCK
TABLES) o implícito con MYISAM, MEMORY o MERGE.
• Bloqueos a nivel de página
– Evita que varios usuarios modifiquen los datos de la misma página de una
tabla (segmento de 2 KB a 16 KB)
– Utilizado por SQL Server y MySQL (implícitamente con BDB)
• Bloqueos a nivel de fila
– Evita que varios usuarios modifiquen los datos de la misma fila de una tabla
simultáneamente.
– Requiere más control por parte del servidor, pero permite que muchos
usuarios modifiquen una tabla simultáneamente si trabajan en diferentes filas.
– Utilizado por SQL Server, Oracle y MySQL (implicitamente con INNODB)
Transacciones
• Es una manera de agrupar varias sentencias SQL de
forma que se ejecuten o “todas” o “ninguna”.
• Los sistemas transaccionales se caracterizan por sus
prestaciones ACID:
– Atomicidad: Las instrucciones de una transacción deben
formar una unidad lógica. No se puede ejecutar solamente
parte de ella.
– Coherencia: la base de datos es coherente antes y después
de ejecutar la instrucción.
– Aislamiento: Una transacción no tiene efecto sobre otra.
– Durabilidad: Tras ejecutar satisfactoriamente una
instrucción, sus efectos se registran permanentemente en
la base de datos.
Iniciar una transacción
• Tenemos dos formas diferentes según el servidor:
– Siempre existe una transacción activa. Cuando
finalizamos una transacción se inicia una nueva (modo
autocommit)
– Indicando que iniciamos la transacción explícitamente
con el comando START TRANSACTION;
• Por defecto nos encontramos en el modo autocommit que
significa que el servidor realiza los cambios solicitados por
las sentencias individuales de forma automática.
• Para desactivar autocommit en una sesión:
SET AUTOCOMMIT = 0;
Finalizar una transacción
• Una vez iniciada una transacción, debemos finalizar esta
para que las modificaciones se conviertan en permanentes
con la instrucción COMMIT;
• Si deseamos deshacer todos los cambios realizados desde
el inicio de la transacción usaremos ROLLBACK;
• Existen otras situaciones que hacen que una transacción
finalice:
– Una caída del servidor
– Ejecutar una instrucción de modificación de esquema, por
ejemplo ALTER TABLE
– Iniciar con START TRANSACTION otra transacción.
– El servidor detecta un bloqueo mutuo (deadlock)
Puntos de guardado
• Si no deseamos deshacer “todo” el trabajo realizado en una
transacción podemos establecer uno o más puntos de
recuperación (savepoints) dentro de la transacción.
• Usaremos el comando:
SAVEPOINT nombre;
• Para retroceder a dicho punto:
ROLLBACK TO SAVEPOINT nombre;
• A tener en cuenta:
– A pesar del nombre, no se guarda nada al crear el punto de
recuperación. Debemos emitir el comando COMMIT si
queremos que la transacción quede reflejada de forma
permanente.
– Si ejecutamos ROLLBACK sin citar un punto de recuperación,
se ignorarán todos los puntos que puedan existir y se deshará la
transacción de forma completa.
Niveles de aislamiento (I)
• Las transacciones especifican un nivel de aislamiento
(la “I” del ACID) que define el grado en que se debe
aislar una transacción de otras. Cada nivel permite o
impide distintos problemas que pueden producirse al
ejecutar varias transacciones a la vez:
– Lectura incorrecta o lectura sucia: Se produce cuando un
cambio efectuado por una transacción lo pueden ver otras
transacciones antes de su confirmación.
– Lecturas no repetidas: La imposibilidad de que una
transacción obtenga el mismo resultado de una
determinada instrucción SELECT cada vez que se ejecuta.
– Filas fantasmas: Son filas visibles para una transacción que
antes no lo eran.
Niveles de aislamiento (II)
NIVEL DE LECTURA LECTURAS NO FILAS FANTASMAS
AISLAMIENTO INCORRECTA REPETIDAS
READ UNCOMMITTED SI SI SI
READ COMMITTED NO SI SI
REPEATABLE READ NO NO NO (*)
SERIALIZABLE NO NO NO
(*) Es NO en el motor INNODB aunque en otros sistemas este nivel si permite filas
fantasma