2010-10-27 10 views
155

Creo que los niveles de aislamiento anteriores son muy parecidos. ¿Podría alguien describir por favor con algunos buenos ejemplos cuál es la principal diferencia?Diferencia entre confirmación de lectura y lectura repetible

+3

Debe ampliar sobre la cuestión y añadir etiquetas para qué "nivel de aislamiento" se está refiriendo a (Java, etc). "nivel de aislamiento" es un término algo ambiguo, y obviamente está pidiendo una respuesta para un entorno específico. – jesup

+3

Probablemente SQL. Esos son algunos de los niveles de aislamiento de transacciones comunes en SQL. – derobert

+0

Sí, eso es cierto, se trata de SQL. Trabajando principalmente con MSSQL, el problema es que después de una gran cantidad de investigaciones en Internet, que puedo encontrar una buena explicación para la diferencia principal entre los dos niveles de aislamiento read commit y lectura repetible, cambiando el título de la pregunta. – Fore

Respuesta

376

Read committed es un nivel de aislamiento que garantiza que cualquier dato leído sea comprometido en el momento en que se lee. Simplemente restringe al lector de ver cualquier lectura intermedia, no comprometida y "sucia". No hace ninguna promesa de que si la transacción vuelve a emitir la lectura, encontrará los mismos datos , los datos son libres de cambiar después de su lectura.

Lectura repetible es un nivel de aislamiento superior, que, además de las garantías del nivel de lectura confirmada, sino que también garantiza que los datos leídos no puede cambiar, si la transacción lee los mismos datos de nuevo, se encuentra el anteriormente leer los datos en su lugar, sin cambios y disponibles para leer.

El siguiente nivel de aislamiento, serializable, hace una garantía aún más fuerte: Además de todo lo garantías de lectura repetible, sino que también garantiza que no hay nuevos datos pueden ser vistos por una lectura posterior.

Digamos que tiene una tabla T con una columna C con una fila, digamos que tiene el valor '1'. Y considerar que tiene una tarea simple como lo siguiente:

BEGIN TRANSACTION; 
SELECT * FROM T; 
WAITFOR DELAY '00:01:00' 
SELECT * FROM T; 
COMMIT; 

Esa es una tarea sencilla que emitir dos lecturas de la tabla T, con un retraso de 1 minuto entre ellos.

  • debajo de LEER Comitted, el segundo SELECT puede devolver cualquier datos. Una transacción simultánea puede actualizar el registro, eliminarlo, insertar nuevos registros. La segunda selección siempre verá los nuevos datos.
  • bajo REPEATABLE READ, el segundo SELECT está garantizado para ver las filas que se han visto al principio, seleccione sin cambios. Se pueden agregar nuevas filas mediante una transacción concurrente en ese minuto, pero las filas existentes no se pueden eliminar ni cambiar.
  • bajo SERIALIZABLE dice que la segunda selección está garantizada para ver exactamente las mismas filas que la primera. Ninguna fila puede cambiar, ni eliminarse, ni se pueden insertar nuevas filas mediante una transacción simultánea.

Si sigue la lógica anterior puede darse cuenta rápidamente de que las transacciones SERIALIZABLE, mientras que pueden hacer la vida más fácil para usted, están siempre bloqueando completamente cada posible operación simultánea, ya que requieren que nadie puede modificar, eliminar ni inserte cualquier fila. El nivel de aislamiento de transacciones por defecto del alcance de .NET System.Transactions es serializable, y esto generalmente explica el rendimiento abismal que resulta.

Y, por último, también está el nivel de aislamiento SNAPSHOT. El nivel de aislamiento de SNAPSHOT ofrece las mismas garantías que la serialización, pero no al requerir que ninguna transacción simultánea pueda modificar los datos, sino al hacer que cada lector vea su propia versión del mundo (su propia "instantánea"). Esto hace que sea muy fácil programar en contra, muy escalable, ya que no bloquea las actualizaciones simultáneas, pero, por supuesto, tiene un precio, y el precio es el consumo de recursos adicionales del servidor.

Suplementario lee:

+19

¡Gracias! Esto fue muy claro y una respuesta informativa. +1 – Phil

+12

Creo que hay un error anterior para REPEATABLE READ: Usted dice que las filas existentes no se pueden eliminar ni cambiar, pero creo que se pueden eliminar o cambiar porque la lectura repetible simplemente lee una "instantánea", no los datos reales. De los documentos http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html#isolevel_repeatable-read: "Todas las lecturas consistentes dentro de la misma transacción leen la instantánea establecida por la primera lectura". –

+1

@Derek Litz Estoy en lo correcto cuando dice: Los datos PUEDEN/PUEDEN ser cambiados de un tercero, mientras se lleva a cabo la transacción, pero las lecturas aún verán los 'viejos' datos originales como si el cambio no hubiera lugar tomado (la instantánea). – Programster

48

Lectura repetible

El estado de la base de datos se mantiene desde el inicio de la transacción. Si recupera un valor en session1, luego actualice ese valor en session2, recuperarlo nuevamente en session1 devolverá 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 

lectura confirmada

En el contexto de una transacción, siempre recuperar el valor más recientemente cometido. Si recupera un valor en session1, lo actualiza en session2, luego lo recupera en session1again, obtendrá el valor modificado en session2. 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?

+0

Intenté lectura repetible en SQL Server 2008 con "establecer lectura repetible de nivel de aislamiento". Creé dos ventanas de consulta sql. Pero no funcionó. ¿Por qué? –

+1

¿Por qué la segunda sesión1 aún leyó a Aaron? ¿La transacción de session2 no está terminada y comprometida? Sé que es viejo, pero tal vez alguien pueda arrojar algo de luz. –

+5

Creo que la lectura repetible bloqueará la segunda sesión hasta la primera sesión confirmada. Entonces el ejemplo es incorrecto – Nighon

9

Pregunta anterior 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 deadlocks como yo.

LEER comprometidos (por defecto)

bloqueos compartidos se toman en el SELECT y luego liberados cuando la instrucción SELECT completa. 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 se complete su SELECCIÓN y antes de que se complete su transacción.

Lectura repetible

bloqueos compartidos se toman en el SELECT y luego liberados sólo después de que finalice la transacción. Así es como el sistema puede garantizar que los valores que lea no cambien durante la transacción (porque permanecen bloqueados hasta que finaliza la transacción).

-1

Mi observación sobre la solución inicial aceptada.

Bajo RR (mysql predeterminado) - Si un tx está abierto y se ha activado un SELECT, otro tx NO puede eliminar ninguna fila perteneciente al conjunto de resultados LEAD anterior hasta que se haya confirmado el tx anterior (de hecho, eliminar declaración en el nuevo tx se colgará), sin embargo, el siguiente tx puede eliminar todas las filas de la tabla sin ningún problema. Por cierto, un próximo READ en tx anterior seguirá viendo los datos antiguos hasta que se confirme.

+2

Es posible que desee ponerlo en la sección de comentarios para que el que responde reciba una notificación. De esa manera, él podrá responder a sus observaciones y hacer correcciones si es necesario. – RBT

9

simplemente la respuesta de acuerdo con mi lectura y la comprensión de este hilo y @ remus-Ruşanu respuesta se basa en este escenario simple:

hay dos procesos A y B. Proceso B es la lectura de la Tabla X Proceso A está escribiendo en la tabla X El proceso B está leyendo nuevamente la Tabla X.

  • READUNCOMMITTED: Proceso B puede leer datos comprometidas del proceso A y se podía ver diferentes filas en función de la escritura B. Sin bloqueo
  • ReadCommitted: El Proceso B solo puede leer datos confirmados del proceso A y podría ver diferentes filas basadas en la escritura B COMPROMETIDA solamente. ¿podríamos llamarlo Simple Lock?
  • RepeatableRead: El proceso B leerá los mismos datos (filas) que el proceso A. Pero el proceso A puede cambiar otras filas. Nivel de filas Bloque
  • Serializable: El proceso B leerá las mismas filas que antes y el Proceso A no podrá leer ni escribir en la tabla. Bloque de nivel de tabla
  • Instantánea: cada proceso tiene su propia copia y están trabajando en ello. Cada uno tiene su propia vista
0

Tratando de explicar esta duda con diagramas simples.

lectura confirmada: Aquí, en este nivel de aislamiento, la transacción T1 va a leer el valor actualizado de los X cometido por transacción T2.

Read Committed

Lectura repetible: En este nivel de aislamiento, la transacción T1 no tendrá en cuenta los cambios confirmados por la transacción T2.

enter image description here

Cuestiones relacionadas