No es un bug, es una característica no documentada

14/4/15

Bases de datos. SQL programado (XII). Transacciones

23:25 Posted by Inazio , No comments
La idea de transacción es un conjunto de operaciones SQL que, o se realizan todas, o no se realiza ninguna.

Un ejemplo de transacción sería una transferencia bancaria. Descuentas de una cuenta e incrementas el dinero en otra. Se han de realizar ambas, si el sistema se cuelga no puede hacerse ninguna de ellas.

Todas las transacciones deben cumplir el principio ACID (Atomic Consistent Isolated Durable). Es decir:

  • Atómica (atomic). Se han de aplicar todas las operaciones de la transacción, o no se ejecuta ninguna
  • Consistente (Consistent). Después de la transacción la base de datos debe quedar en un estado consistente, es decir, con los datos correctamente almacenados
  • Aislada (Isolated). Una transacción no debe interferir con otras transacciones que se estén llevando a cabo de forma simultánea
  • Permanente (Durable). Se deben mantener los datos para que perduren en el tiempo, aun cuando la base de datos o el equipo fallen.

Niveles de aislamiento

Determinan la manera en la que las transacciones de una sesión pueden afectar a los datos recuperados o accedidos por otra sección.

  • Lectura no confirmada. El nivel más bajo. Permite que una transacción pueda leer filas que todavía no han sido confirmadas (COMMIT). Aumenta el rendimiento pero no justifica que se pueda permitir a un usuario leer datos modificados por otro usuario cuando aún pueden deshacer dichas modificaciones
  • Lectura confirmada. Sólo se permite lectura de datos que han sido confirmados. Confirmar con COMMIT. Con este trabaja ORACLE
  • Lectura repetible. Nivel por defecto. Hasta que un usuario no haga un fin de transacción, no podrá ver los cambios realizados por otros usuarios.
  • Secuenciable. Mayor nivel de aislamiento. No sólo bloquea las operaciones DML, si no hasta los propios SELECT. Es decir, no sólo bloquea las filas que estás modificando, sino también incluso las que estás consultando.

Vamos a trabajar por línea de comandos. Abrimos dos consolas de cliente por líne a de comandos, y hacemos en ambas los siguientes pasos:

Lo primero es realizar un

select connection_id();

Para que nos devuelve el identificador de usuario. Lo hacemos en ambas consolas.




A continuación deshabilitamos en ambas sesiones el autocommit para controlar nosotros mismos las transacciones (es decir, para deshabilitar las lecturas no confirmadas). Lo hacemos en ambas consolas también.

set @@autocommit = 0; -- Deshabilito el autocommit
show variables like ‘autocommit’; -- veo si se han realizado los cambios



Trabajemos ahora con el nivel por defecto de MySQL.

Ahora, realizo un update normal

update alumnos set alumno = ‘dos’

Y para confirmar los datos realizamos un

commit;

Ahora, en la segunda consola, escribimos un

commit;

Y podremos ya ver los cambios modificados por otro usuario, y los nuestros también, por supuesto.

Ahora bien, si el primer usuario no quiere guardar los cambios realizados, usaremos el comando

rollback;


Este comando deshace todas las modificaciones realizadas por la transacción.

Por supuesto, si el usuario dos intenta modificar una fila empleada por el usuario uno, la instrucción ejecutada por el usuario dos quedará en espera durante el tiempo especificado en el motor de la base de datos, confiando en que usuario uno termina su actualización antes de llegar al máximo permitido.

Para configurar el tiempo de espera, lanzamos un 

select variables;

0 comments:

Publicar un comentario