Permisos y transacciones
Quién puede hacer qué sobre cada objeto, qué es una transacción y qué garantiza, cómo se abre y se cierra, y qué problemas de concurrencia evita cada nivel de aislamiento.
GRANT y REVOKE
El control de acceso se reduce a dos sentencias. GRANT concede uno o varios privilegios sobre un objeto a un usuario o a un rol, y REVOKE se los retira. La estructura es simétrica y conviene fijarse en la preposición, porque es lo que las distingue de un vistazo: se concede a alguien y se retira de alguien.
GRANT SELECT, INSERT ON intento TO profesor;
-- El privilegio puede acotarse a columnas concretas
GRANT UPDATE (modalidad) ON alumno TO soporte;
-- EXECUTE es el privilegio de los procedimientos
GRANT EXECUTE ON PROCEDURE registrar_intento TO aplicacion;
-- Con delegación: quien lo recibe puede concedérselo a otros
GRANT ALL ON tema TO coordinador WITH GRANT OPTION;
REVOKE INSERT ON intento FROM profesor;- SELECT, INSERT, UPDATE y DELETE: las operaciones del DML sobre el objeto. Los de actualización e inserción admiten además una lista de columnas, de modo que el permiso no alcance a toda la fila.
- EXECUTE: ejecutar un procedimiento o una función.
- USAGE: utilizar un objeto que no contiene filas, como una secuencia.
- ALL: todos los privilegios aplicables al objeto de una vez.
WITH GRANT OPTION es la cláusula que hay que mirar con cuidado: no añade ningún permiso sobre los datos, añade la capacidad de repartirlo. Quien recibe un privilegio con esa cláusula puede concedérselo a su vez a terceros, con lo que el control deja de estar en un solo sitio.
El rol es un conjunto de privilegios con nombre. Conceder al rol y asignar el rol a las personas evita tener que repetir la misma lista de GRANT para cada usuario nuevo.
Para el examen
GRANT … TO: concede
REVOKE … FROM: retira
EXECUTE: el privilegio de los procedimientos
WITH GRANT OPTION: permite delegar el permiso a terceros
La transacción y las propiedades ACID
Una transacción es un conjunto de sentencias SQL que tienen que ejecutarse todas o ninguna. No hay término medio: o el trabajo queda entero o la base de datos se queda como estaba antes de empezar. Por eso se dice que es un proceso atómico, en el sentido de indivisible.
El ejemplo de manual es el traspaso entre dos cuentas, con su cargo y su abono, pero vale cualquier operación que toque más de una tabla: registrar un intento y actualizar el resumen del tema tiene que pasar de golpe, porque un resumen actualizado sin su intento, o al revés, es una base de datos incoherente.
| Propiedad | Qué garantiza |
|---|---|
| Atomicidad | La transacción se aplica entera o no se aplica nada de ella |
| Consistencia | Se parte de un estado válido y se llega a otro válido: no se dejan restricciones incumplidas |
| Aislamiento | Las transacciones simultáneas no se estorban: cada una trabaja como si estuviera sola |
| Durabilidad | Una vez confirmada, el cambio persiste aunque el sistema se caiga inmediatamente después |
Para el examen
Atomicidad: todo o nada
Consistencia: de estado válido a estado válido
Aislamiento: las transacciones simultáneas no se estorban
Durabilidad: lo confirmado persiste
Abrir, confirmar y deshacer
Las sentencias del control de transacciones marcan el principio y el final de esa unidad de trabajo. COMMIT confirma los cambios y los hace permanentes y visibles para los demás; ROLLBACK los deshace y devuelve la base al estado en que estaba al empezar. Mientras no haya COMMIT, nada de lo hecho es definitivo.
START TRANSACTION;
INSERT INTO intento (id_intento, id_alumno, id_tema, aciertos, fallos, realizado)
VALUES (5001, 1, 7, 18, 2, CURRENT_TIMESTAMP);
SAVEPOINT antes_del_resumen;
UPDATE resumen_tema SET intentos = intentos + 1 WHERE id_tema = 7;
-- Se descarta solo el UPDATE; el INSERT sigue en pie
ROLLBACK TO SAVEPOINT antes_del_resumen;
COMMIT;- START TRANSACTION abre la transacción y END TRANSACTION la cierra. Muchos gestores la abren solos con la primera sentencia si no se hace expresamente.
- SAVEPOINT crea un punto de salvaguarda intermedio con nombre.
- ROLLBACK TO SAVEPOINT vuelve a ese punto y descarta solo lo hecho desde entonces, dejando en pie lo anterior. La transacción sigue abierta.
- RELEASE SAVEPOINT elimina un punto de salvaguarda que ya no hace falta.
- SET TRANSACTION configura la transacción antes de empezar, y es donde se fija el nivel de aislamiento.
Un ROLLBACK a secas deshace la transacción entera; un ROLLBACK a un savepoint deshace solo un tramo y deja la transacción viva.
Para el examen
COMMIT: confirma y hace visibles los cambios
ROLLBACK: deshace la transacción entera
ROLLBACK TO SAVEPOINT: descarta solo un tramo y deja la transacción abierta
SET TRANSACTION: fija el nivel de aislamiento
Los tres problemas de la concurrencia
Cuando varias transacciones trabajan a la vez sobre los mismos datos aparecen tres anomalías clásicas. Hay que saber distinguirlas porque son las que definen los niveles de aislamiento, y se distinguen por lo que ve una transacción que lee dos veces.
- Lectura sucia: una transacción lee datos que otra ha modificado y todavía no ha confirmado. Si esa otra acaba deshaciendo su trabajo, lo leído nunca llegó a existir.
- Lectura no repetible: una transacción lee una fila, otra la modifica y confirma, y al volver a leerla la primera encuentra valores distintos de los que había visto.
- Lectura fantasma: una transacción consulta un conjunto de filas con una condición, otra inserta una fila nueva que también la cumple y confirma, y al repetir la consulta aparece una fila que antes no estaba.
La diferencia entre las dos últimas es la que se pregunta, y está en qué cambia. En la no repetible cambia el valor de una fila que ya se había leído; en la fantasma no cambia ninguna fila conocida, sino que aparece una nueva dentro del rango consultado. De ahí el nombre: la fila no estaba y se ha materializado.
Para el examen
Lectura sucia: leer datos no confirmados
Lectura no repetible: una fila ya leída cambia de valor
Lectura fantasma: aparece una fila nueva dentro del rango consultado
Los niveles de aislamiento
El nivel de aislamiento se fija con SET TRANSACTION y es la palanca con la que se decide cuánta concurrencia se tolera. Cada escalón elimina una anomalía más y, a cambio, obliga al gestor a bloquear más y a dejar pasar menos trabajo a la vez.
| Nivel | Lectura sucia | Lectura no repetible | Lectura fantasma |
|---|---|---|---|
| READ UNCOMMITTED | La permite | La permite | La permite |
| READ COMMITTED | La evita | La permite | La permite |
| REPEATABLE READ | La evita | La evita | La permite |
| SERIALIZABLE | La evita | La evita | La evita |
READ COMMITTED es el nivel que aplican por defecto la mayoría de gestores, y es el punto de equilibrio razonable: no se leen datos sin confirmar, pero se admite que lo leído cambie a lo largo de la transacción. En el extremo opuesto, SERIALIZABLE deja el resultado igual que si las transacciones se hubieran ejecutado una detrás de otra, y es el único que llega a bloquear rangos enteros y no solo las filas concretas ya leídas. Es el más seguro y el que menos rendimiento da.
Los cuatro niveles van en escala: cada uno evita todo lo que evita el anterior y una anomalía más. Cuanto más aislamiento, menos concurrencia.
Para el examen
READ UNCOMMITTED: el más permisivo: admite lectura sucia
READ COMMITTED: el habitual por defecto
REPEATABLE READ: aún permite fantasmas
SERIALIZABLE: las evita todas, a costa de concurrencia