Creo que los niveles de aislamiento anteriores son muy parecidos. ¿Podría alguien describir con algunos buenos ejemplos cuál es la principal diferencia?
Creo que los niveles de aislamiento anteriores son muy parecidos. ¿Podría alguien describir con algunos buenos ejemplos cuál es la principal diferencia?
Respuestas:
Leer confirmado es un nivel de aislamiento que garantiza que cualquier lectura de datos se confirmó en el momento en que se lee. Simplemente restringe al lector de ver cualquier lectura intermedia, no comprometida, 'sucia'. No promete nada que si la transacción vuelve a emitir la lectura, encontrará los mismos datos, los datos son libres de cambiar después de ser leídos.
La lectura repetible es un nivel de aislamiento más alto, que además de las garantías del nivel comprometido de lectura, también garantiza que cualquier lectura de datos no puede cambiar , si la transacción lee los mismos datos nuevamente, encontrará los datos leídos previamente en su lugar, sin cambios. y disponible para leer.
El siguiente nivel de aislamiento, serializable, ofrece una garantía aún más sólida: además de todas las garantías de lectura repetibles, también garantiza que no se puedan ver nuevos datos en una lectura posterior.
Digamos que tiene una tabla T con una columna C con una fila, digamos que tiene el valor '1'. Y considere que tiene una tarea simple como la siguiente:
BEGIN TRANSACTION;
SELECT * FROM T;
WAITFOR DELAY '00:01:00'
SELECT * FROM T;
COMMIT;
Esa es una tarea simple que emite dos lecturas de la tabla T, con un retraso de 1 minuto entre ellas.
Si sigue la lógica anterior, puede darse cuenta rápidamente de que las transacciones SERIALIZABLES, si bien pueden facilitarle la vida, siempre bloquean por completo todas las operaciones concurrentes posibles, ya que requieren que nadie pueda modificar, eliminar ni insertar ninguna fila. El nivel de aislamiento de transacción predeterminado del System.Transactions
ámbito .Net es serializable, y esto generalmente explica el rendimiento abismal que resulta.
Y finalmente, también está el nivel de aislamiento SNAPSHOT. El nivel de aislamiento SNAPSHOT ofrece las mismas garantías que serializable, pero no requiere que ninguna transacción concurrente pueda modificar los datos. En cambio, obliga a cada lector a ver su propia versión del mundo (es su propia "instantánea"). Esto hace que sea muy fácil programar y muy escalable, ya que no bloquea las actualizaciones simultáneas. Sin embargo, ese beneficio tiene un precio: consumo adicional de recursos del servidor.
Lecturas suplementarias:
El estado de la base de datos se mantiene desde el inicio de la transacción. Si recupera un valor en la sesión1, luego actualice ese valor en la sesión2, recuperarlo nuevamente en la sesión1 arrojará los mismos resultados. Las lecturas son repetibles.
session1> BEGIN;
session1> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> BEGIN;
session2> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> UPDATE names SET firstname = 'Bob' WHERE id = 7;
session2> SELECT firstname FROM names WHERE id = 7;
Bob
session2> COMMIT;
session1> SELECT firstname FROM names WHERE id = 7;
Aaron
Dentro del contexto de una transacción, siempre recuperará el valor comprometido más reciente. Si recupera un valor en la sesión1, actualícelo en la sesión2, luego recupérelo en la sesión1 nuevamente, obtendrá el valor modificado en la sesión2. Lee la última fila comprometida.
session1> BEGIN;
session1> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> BEGIN;
session2> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> UPDATE names SET firstname = 'Bob' WHERE id = 7;
session2> SELECT firstname FROM names WHERE id = 7;
Bob
session2> COMMIT;
session1> SELECT firstname FROM names WHERE id = 7;
Bob
¿Tiene sentido?
Simplemente la respuesta de acuerdo con mi lectura y comprensión de este hilo y la respuesta @ remus-rusanu se basa en este escenario simple:
Hay dos procesos A y B. El proceso B está leyendo la Tabla X El proceso A está escribiendo en la tabla X El proceso B está leyendo nuevamente la Tabla X.
Antigua pregunta que ya tiene una respuesta aceptada, pero me gusta pensar en estos dos niveles de aislamiento en términos de cómo cambian el comportamiento de bloqueo en SQL Server. Esto podría ser útil para aquellos que están depurando puntos muertos como yo.
LEER COMPROMETIDO (predeterminado)
Los bloqueos compartidos se toman en SELECT y luego se liberan cuando se completa la instrucción SELECT . Así es como el sistema puede garantizar que no haya lecturas sucias de datos no confirmados. Otras transacciones aún pueden cambiar las filas subyacentes después de que su SELECT finalice y antes de que finalice su transacción.
LECTURA REPETIBLE
Los bloqueos compartidos se toman en SELECT y luego se liberan solo después de que se completa la transacción . Así es como el sistema puede garantizar que los valores que lea no cambiarán durante la transacción (porque permanecen bloqueados hasta que finaliza la transacción).
Tratando de explicar esta duda con diagramas simples.
Lectura confirmada: aquí, en este nivel de aislamiento, la transacción T1 leerá el valor actualizado de la X confirmada por la transacción T2.
Lectura repetible: en este nivel de aislamiento, la Transacción T1 no considerará los cambios confirmados por la Transacción T2.
Creo que esta imagen también puede ser útil, me ayuda como referencia cuando quiero recordar rápidamente las diferencias entre los niveles de aislamiento (gracias a kudvenkat en youtube)
Tenga en cuenta que lo repetible en lectura repetible se refiere a una tupla, pero no a toda la tabla. En los niveles de aislamiento ANSC, puede ocurrir una anomalía de lectura fantasma , lo que significa leer una tabla con la misma cláusula donde dos veces puede devolver diferentes conjuntos de resultados diferentes. Literalmente, no es repetible .
Mi observación sobre la solución inicial aceptada.
Bajo RR (mysql predeterminado): si un tx está abierto y se ha disparado un SELECT, otro tx NO puede eliminar ninguna fila que pertenezca al conjunto de resultados READ anterior hasta que se confirme el tx anterior (de hecho, la instrucción de borrado en el nuevo tx simplemente se bloqueará) , sin embargo, el siguiente tx puede eliminar todas las filas de la tabla sin ningún problema. Por cierto, una próxima LECTURA en tx anterior todavía verá los datos antiguos hasta que se confirmen.