Buenas,
Nos juntamos a estudiar Isolation Levels entre compañeros.
Parece que Moscuzza dá este tema de una forma bastante diferente, con ejercicios y todo.
En estos finales se resuelven ejercicios de Isolation:
http://www.utnianos.com.ar/foro/tema-fin...18-12-2012
http://www.utnianos.com.ar/foro/tema-apo...26-05-2014
Mi idea con este thread es darle un punto final al tema, que no haya varias versiones sobre cómo se resuelven estos ejercicios y cómo hay que entender la teoría.
A continuación les explico todo lo que yo entendí sobre el tema, según mis apuntes. Si ven algo mal, o no se entiende algo, corrijanmé:
______________
LECTURA REPETIBLE / NO REPETIBLE:
Una lectura repetible ocurre cuando en el curso de una transacción un select se lee N veces y los valores coinciden.
Una lectura no repetible ocurre cuando en el curso de una transacción un select se lee N veces y, tras las operaciones de OTRA transacción, los valores no coinciden.
Ejemplo:
Suponiendo que la tabla "usuarios" está formado por dos columnas (id , nombre) y tiene tres registros con id = 1 ....
BEGIN TRAN T1;
SELECT * FROM usuarios WHERE id = 1;
SELECT * FROM usuarios WHERE id = 1;
COMMIT TRAN T1;
... Si en las dos consultas me devuelve los tres registros con los mismos nombres, entonces se dice que la lectura para ESTA transacción es REPETIBLE. Si alguno de esos tres registros aparece CAMBIADO (donde estaba JUAN ahora aparece PEDRO), entonces la lectura es NO REPETIBLE.
Si en ese SELECT aparecen menos de 3 registros, también la lectura es NO REPETIBLE.
Pero si aparecen más registros, las lecturas son repetibles con "registros fantasma".
En conclusión: si en algún momento la tabla 'usuarios' sufre un DELETE o UPDATE en otra transacción
que se commitea y yo puedo VER esos cambios dentro del transcurso de mi transacción, entonces mi transacción es de lecturas NO REPETIBLES.
LECTURA FANTASMA
Volviendo al ejemplo de recién...
Si en el primer select aparecen 3 registros y en el segundo aparecen 4 registros, entonces la lectura es REPETIBLE con lectura FANTASMA.
O sea, la lectura fantasma
es un caso particular de las lecturas no repetibles... es cuando la tabla puede sufrir INSERTs desde otras transacciones y yo pueda verlas en la mia, pero sí ocurren DELETES o UPDATES yo esos cambios no los veo.
La lectura fantasma siempre aparece tras el COMMIT de OTRA transacción. Si aparece sin que otra transacción se haya commiteado, entonces vamos a estar hablando de una Lectura Sucia.
LECTURA SUCIA
Una lectura sucia ocurre cuando en el curso de una transacción un select se lee N veces y, tras la ejecución de otras transacciones que NO SE COMMITEAN, los valores de los select de mi transacción no coinciden.
Ejemplo:
Usuario 1
BEGIN TRAN T1;
SELECT * FROM usuarios WHERE id = 1;
WAITFOR DELAY '00:00:05'
SELECT * FROM usuarios WHERE id = 1;
COMMIT TRAN T1;
Usuario 2
INSERT INTO usuarios (id, nombre) VALUES (2,"José");
BEGIN TRAN T2;
UPDATE usuarios SET usuario="Caro" WHERE id = 1;
... suponiendo que la transacción T2 no cierra nunca, de cualquier forma, tanto el INSERT como el UPDATE se verán impactados en el segundo SELECT de la T1 (también suponiendo que el usuario 2 corre el script mientras T1 está esperando en el WAITFOR).
NIVELES DE AISLAMIENTO
.... Teniendo en claro estos conceptos, ahora puedo hablar sobre los niveles de aislamiento:
Con entender estos conceptos, es más fácil saber en qué nivel de aislamiento estoy.
-
READ UNCOMMITED: Puedo hacer lecturas sucias. Sería el equivalente a no darle bola a las transacciones, a poder "leer todo" esté o no commiteado.
Si hago un SELECT, no bloqueo nada.
-
READ COMMITED: Dentro de una transacción puedo ver dos SELECTs iguales con resultados totalmente diferentes SIEMPRE Y CUANDO otra transacción commitee sus operaciones.
Si hago un SELECT, no bloqueo nada.
-
REPETEABLE READS: Idem al anterior, pero sólo aplica a lecturas fantasma.
Si hago un SELECT en mi Transacción A, bloqueo el rango de registros del WHERE.
Si otra transacción B quiere hacer INSERTs sobre esa tabla, va a poder sin problemas, y la Transacción A va a poder ver esos registros nuevos (los "fanstasmas"), pero si además quiere aplicar UPDATEs y DELETEs, esas operaciones se van a bloquear, deteniendo la ejecución de TB. Cuando TA commitee, TB va a reanudar su hilo por donde estaba.
-
SERIALIZABLE: hasta que yo no commitee mi transacción, dentro de ella no voy a poder ver ningún tipo de cambio hecho por otras transacciones. Si hago un SELECT, voy a bloquear ese rango de registros, impidiendo a otras transacciones tocar lo que estoy usando para asegurar así Lecturas Repetibles.
BLOQUEOS DE ESCRITURA / LECTURA / RANGO
Explicado arriba. En Wikipedia hay una tabla donde explican mejor el concepto según Isolation Level.
OPERACIONES SIN TRANSACCIONES
Si tengo, por ej, una operación SELECT por fuera de toda transacción definida por BEGIN y COMMIT, esta representa una transacción en sí misma.
O sea, por ej:
SELECT * FROM tabla
.... es el equivalente a escribir:
BEGIN TRAN T1
SELECT * FROM tabla
COMMIT TRAN T1
.... todo ese bloque ejecutado en un mismo instante de tiempo (siempre hablando de los ejercicios que se toman en los finales, claro está... en la realidad los tiempos deben diferir, supongo).