Sunteți pe pagina 1din 10

Práctica de Transacciones

NIVEL BASICO PRINCIPIOS BASICOS Y COMANDOS MYSQL

Parte 1

 Iniciar phpmyadmin y crear una base de datos de prueba, con una tabla llamada
Cliente en los siguientes atributos id_cli, nom-cli y valor (clave principal, nombre del cliente
y valor arbitrario)

Parte 2

 Iniciar el terminal del sistema operativo y escribir el comando siguiente

mysql -u login -p (escribir el password pegado de la letra p)

ejemplo mysql -u root -p1234

Parte 3

 Teclear help para observar e identificar los comandos de mysql asi como su
descripción.

 Interesan los siguientes comandos: show databases , use (nombre de la base de


datos), show tables , describe (nombre de la tabla)...

Parte 4 EL COMMIT

 Verificamos que tengamos abierto phpmyadmin y el terminal en el escritorio

 Iniciamos en el terminal con el comando update set where

 Verificamos que se hizo el autocommit actualizando la base de datos en el


phpmyadmin

si es correcto, empezaremos una transaccion simple como sigue:

begin;

update set where;

 Actualizamos en phpmyadmin y observamos si hubo cambio en la información.

no debe haber sucedido nada en absoluto de lo contrario sucedio un autocommit por que
no se verifico el comando begin o sucedio un error inesperadosi todo sale bien y no hay
cambios hacemos commit
commit;

 Verificamos actualizando phpmyadmin y en efecto se actualiza los cambios en el


registro.

 Hacemos la misma prueba desde el inicio on begin luego update pero esta vez con
el comando rollback

begin;

update set where;

rollback;

Parte 5 EL ROLLBACK TO SAVE POINT

 Hacemos parecido al rollback pero con cada consulta guardamos en un savepoint,


de esa manera podemos ir atrás a un punto específico de guardado

o Begin;

o Insert into table(at1,at2,at3 ) values(v1,v2,v3);

o Savepoint uno;

o Insert into table(at1,at2,at3 ) values(v1,v2,v3);

o Savepoint dos;

o Insert into table(at1,at2,at3 ) values(v1,v2,v3);

o Savepoint tres;

o Select * from table;

o Rollback to savepoint uno;

o Select * from table;

o Commit / rollback;

 El comando “release savepoint”, elimina el savepoint para ello hay que indicar
como se nombra por ejemplo.

o Release savepoint dos;


o Rollback savepoint dos; (dará un error indicando que no xiste ese
savepoint)

FIN NIVEL BASICO

INICIO DEL NIVEL INTERMEDIO LECTURAS CONSISTENTES(AISLAMIENTO) SIN BLOQUEOS

Paso 1
Iniciamos ahora la práctica del aislamiento en las transacciones, es decir como sucede la
concurrencia en las transacciones y para eso necesitamos dos procesos o sesiones abiertas que
simularan como si fueran dos usuarios diferentes viendo la misma tabla de datos, la idea es saber
que cambios ve un usuario respecto del otro cuando se inicia una transacción simple.

paso 2
Iniciaremos dos terminales por defecto es decir sin invocar ningún tipo de aislamiento por defecto
mysql asume predeterminado como repeatable read nivel 3 para evitar los problemas de lecturas
no repetidas ...como estamos en mysql una lectura confirmada o read commited no debe verse la
tabla modificada por ninguno de los dos usuarios sino hasta después del commit.

Verifiquemos el aislamiento con SHOW VARIABLES LIKE 'tx_isolation'

También es posible establecer el nivel de aislamientor con el argumento --transation-isolation o


modificando el fichero de configuración del servidor my.cfg.

Paso 3 Lectura no confirmada en nivel 1 de concurrencia alta y bajo aislamiento

Lectura no confirmada en nivel 1 de concurrencia alta y bajo aislamiento produce el


Problema de anomalía de lectura sucia o dirty read
tiempo Usuario 1 Usuario 2
1 Begin; Begin;

2 Set transation isolation level read Set transation isolation level read
uncommitted; uncommitted;
3 Select * from table; Select * from table;
4 Update set where;
5 Select * from table;
6 Select * from table;
7 Commit; Rollback;
En el tiempo 3 ambos usuarios ven lo mismo, en el tiempo 5 el usuario 1 lee el cambio, en el
tiempo 6 el usuario 2 también lee el cambio se produce la anomalia(lectura sucia) antes del
commit/rollback de ambos.
Paso 4 Lectura confirmada en nivel 2 de concurrencia poco alta y aislamiento poco bajo

Lectura confirmada en nivel 2 de concurrencia poco alta y poco bajo aislamiento produce
el Problema de anomalía de lectura no repetible
tiempo Usuario 1 Usuario 2
1 Begin; Begin;

2 Set transation isolation level read Set transation isolation level read
committed; committed;
3 Select * from table; Select * from table;
4 Update set where;
5 Select * from table;
6 Select * from table;
7 Commit;
8 Select * from table;
9 Rollback;
En el tiempo 3 ambos leen la misma lectura pero en el tiempo 5 el usuario 1 lee el cambio y
en el tiempo 6 el usuario 2 no lee el cambio, sigue leyendo el anterior, en el tiempo 8 el
usuario 2 lee el cambio(lectura no repetible) después que el usuario 1 da el commit, el
problema es que el usuario 2 no ha dado commit y lee el cambio lo que es irregular.

Paso 5 Lectura Repetible en nivel 3 de concurrencia baja y aislamiento alto

Lectura repetible en nivel 3 de concurrencia baja y aislamiento alto produce el Problema


de anomalía de lectura fantasma
tiempo Usuario 1 Usuario 2
1 Begin; Begin;

2 Set transation isolation level Set transation isolation level repeatable


repeatable read; read;
3 Select * from table; Select * from table;
4 Update set where;
5 Select * from table;
6 Select * from table;
7 Commit;
8 Select * from table;
9 Rollback;
En el tiempo 3 ambos leen la misma lectura pero en el tiempo 5 el usuario 1 lee el cambio y
en el tiempo 6 el usuario 2 no lee el cambio, sigue leyendo el anterior, en el tiempo 8 el
usuario 2 no lee el cambio(lectura es repetible)sino la letura inicial aun después que el
usuario 1 da el commit, ahora el usuario 2 ha dado commit y ya pude leer el cambio lo que
es normal, a veces aparecen anomaliás menores llamadas “las lecturas fantasma” que se
dan en condiciones especiales.

Paso 6 Ejemplo Serializable en nivel 4 concurrencia cero

Serializable en nivel 3 de concurrencia baja y aislamiento alto produce el Problema de


anomalía de lectura fantasma
tiem Usuario 1 Usuario 2
po
1 Begin; Begin;
2 Set transation isolation level serializable; Set transation isolation level serializable;
3 Select * from tabla; Select * from tabla;
4 Insert into tabla(a,b,c ) values(1,’2’,’3’);
5 Commit;
6 Select * from tabla;
7 Commit;
Las lecturas fantasma se dan en condiciones especiales cuando un usuario en tiempo 3 lanza
una consulta de selección con una condición y recibe en ese momento N filas y vuelve a lanzar
en tiempo 5 la misma consulta junto con la misma condición y recibe M filas con M > N. Esto
es a que durante el intervalo que va de la primera a la segunda lectura se insertaron nuevas
filas en el usuario 2 en tiempo 4 y luego dio commit antes que la condición impuesta en la
consulta del usuario 1 en tiempo 6.

Observación: en la versión nueva 2015-16 de MySql no suceden los problemas fantasmas con el
nivel 3 repeatable read o lectura repetible, sino que funciona como si fuese serializable, y
realmente no es serializable sino que mysql implemento un algoritmo llamado Next-Key Locking.

Técnica Bloqueo de la próxima clave (Next-Key Locking): evitar el problema fantasma

 En el bloqueo a nivel de fila, InnoDB utiliza un algoritmo llamado bloqueo de


próxima clave. InnoDB lleva a cabo el bloqueo a nivel de fila de tal manera que cuando
busca o recorre el índice de una tabla, establece bloqueos compartidos o exclusivos en los
registros de índice que encuentra. Por lo tanto, los bloqueos a nivel de fila son en realidad
bloqueos sobre registros del índice.
 Cuando InnoDB recorre un índice, también puede bloquear la posición vacía
después del último registro del índice. Es precisamente lo que ocurre en el ejemplo
anterior: Los bloqueos impuestos por InnoDB evitan cualquier inserción en la tabla donde
id fuera mayor de 100.

Paso 7 Bloqueo Compartido Select… Lock in share mode

Bloqueo compartido En Cascada

tiem Usuario 1 Usuario 2


po
1 Set transation isolation level read Set transation isolation level read
committed; committed;
2 Begin; Begin;
3 Select * from table; Select * from tabla;
4 Select * from table where id_cli=1 lock
in share mode;
5 Select * from table where id_cli=1 lock in
share mode;
6 Select * from table where id_cli=1 for
update;
7 Commit;

Observe lo que sucede con los interbloqueos en cascada compartido-compartido y


luego exclusivo….el terminal se queda en espera al commit del usuario 2.

Estas reglas pueden resumirse convenientemente por medio de una matriz de


compatibilidad entre tipos de bloqueo(revisar cuadro)

Paso 8 Bloqueo Exclusivo Select …for update

Bloqueo Exclusivo en Cascada

tiempo Usuario 1 Usuario 2


1 Set transation isolation level read Set transation isolation level read
committed; committed;
2 Begin; Begin;
3 Select * from tabla;
4 Select * from tabla;
5 Select * from table where id_cli=1
for update;
6 Select * from table where id_cli=1 for
update;
7 Commit;

Observe lo que sucede con los interbloqueos en cascada exclusivo-exclusivo … el


terminal se queda en espera al commit del usuario 1. Estas reglas pueden resumirse
convenientemente por medio de una matriz de compatibilidad entre tipos de
bloqueo(revisar cuadro)

FIN DEL NIVEL INTERMEDIO

COMIENZO DEL NIVEL AVANZADO BLOQUEOS E INTERBLOQUEOS

Modos de bloqueo InnoDB

InnoDB implementa un bloqueo a nivel de fila estándar, donde hay dos tipos de bloqueos:

 Compartido (Shared) (S) le permite a una transacción leer una fila.

 Exclusivo (Exclusive) (X) le permite a una transacción actualizar o eliminar


una fila.

Adicionalmente, InnoDB soporta bloqueo de granularidad múltiple (multiple granularity


locking), el cual permite que existan simultáneamente bloqueos en registros y bloqueos en
tablas enteras. Para hacer práctico el nivel de bloqueo de granularidad múltiple, se emplean
tipos adicionales de bloqueo, llamados bloqueos de intención (intention locks). Los
bloqueos de intención son bloqueos de tabla en InnoDB. La idea detrás de los mismos es
que una transacción indique qué tipo de bloqueo (compartido o exclusivo) requerirá más
tarde sobre una fila de esa tabla. En InnoDB se utilizan dos tipos de bloqueos de intención
(asumiendo que la transacción T ha solicitado un bloqueo del tipo indicado en la tabla R):

 Intención compartida (Intention shared) (IS): La transacción T trata de


establecer bloqueos S en tuplas individuales de la tabla T.
 Intención exclusiva (Intention exclusive) (IX): La transacción T trata de
establecer bloqueos X en las tuplas.

Estas reglas pueden resumirse convenientemente por medio de una matriz de


compatibilidad entre tipos de bloqueo:

X IX S IS -
X N S S N S
IX S S S S S
S S S S S S
IS S S S S S
- S S S S S

Cómo tratar con interbloqueos

Los deadlocks son un problema clásico de las bases de datos transaccionales, pero no son
peligrosos a menos que sean tan frecuentes que no se puedan ejecutar en absoluto ciertas
transacciones. Normalmente, las aplicaciones deben ser escritas de modo que estén
preparadas para emitir nuevamente una transacción si ésta es cancelada debido a un
deadlock.

InnoDB emplea bloqueos automáticos a nivel de fila. Se pueden producir deadlocks aún en
el caso de transacciones que solamente insertan o eliminan una fila individual. Esto se debe
a que estas operaciones no son realmente “atómicas”; sino que establecen automáticamente
bloqueos en los (posiblemente varios) registros de índice de la fila insertada o eliminada.

Con las siguientes técnicas se puede estar a cubierto de los deadlocks y reducir la
probabilidad de que ocurran:

Emplear SHOW ENGINE innodb STATUS para determinar la causa del último deadlock.
Puede ayudar a afinar la aplicación para evitar que ocurran otros.
Siempre hay que estar preparado para emitir nuevamente una transacción que haya fallado
por un deadlock. Los deadlocks no revisten peligro, simplemente hay que intentar de
nuevo.

Confirmar las transacciones frecuentemente. Las transacciones pequeñas son menos


propensas a originar conflictos.

Si se están usando lecturas que establecen bloqueos (SELECT ... FOR UPDATE o ...
LOCK IN SHARE MODE), hay que intentar utilizar un nivel de aislamiento bajo, como
READ COMMITTED.

Acceder a las tablas y filas en un orden fijo. Entonces, las transacciones forman secuencias
bien definidas y no originan deadlocks.

Agregar a las tablas índices adecuadamente elegidos. Entonces las consultas necesitarán
examinar menos registros de índice y en consecuencia establecerán menos bloqueos.
Utilizar EXPLAIN SELECT para determinar los índices que MySQL considera más
apropiados para las consultas.

Utilizar menos el bloqueo. Si es aceptable que SELECT devuelva datos de una captura de
la base de datos que no sea la más actualizada, no hay que agregarle las cláusulas FOR
UPDATE o LOCK IN SHARE MODE. En este caso es adecuado utilizar el nivel de
aislamiento READ COMMITTED, porque cada lectura consistente dentro de la misma
transacción leerá de su propia captura más reciente.

Si nada de esto ayuda, habrá que serializar las transacciones con bloqueos a nivel de tabla.
La forma correcta de emplear LOCK TABLES con tablas transaccionales, como InnoDB,
es establecer AUTOCOMMIT = 0 y no invocar a UNLOCK TABLES hasta que se haya
confirmado explícitamente la transacción. Por ejemplo, si se necesitara escribir en una tabla
t1 y leer desde una tabla t2, se puede hacer esto:

SET AUTOCOMMIT=0;

LOCK TABLES t1 WRITE, t2 READ, ...;


[aquí se hace algo con las tablas t1 y t2];

COMMIT;

UNLOCK TABLES;

Los bloqueos a nivel de tabla favorecen el funcionamiento de la cola de transacciones, y


evitan los deadlocks.

Otra manera de serializar transacciones es crear una tabla “semáforo” auxiliar que contenga
sólo una fila. Hay que hacer que cada transacción actualice esa fila antes de acceder otras
tablas. De ese modo, todas las transacciones se producirán en serie. Nótese que el algoritmo
de detección instantánea de deadlocks de InnoDB también funciona en este caso, porque el
bloqueo de serialización es un bloqueo a nivel de fila. Con los bloqueos a nivel de tabla de
MySQL, debe emplearse el método de timeout para solucionar deadlocks.

En aquellas aplicaciones que emplean el comando de MySQL LOCK TABLES, MySQL


no establece bloqueos de tabla si AUTOCOMMIT=1.

S-ar putea să vă placă și