Beneficios de SET TRANSACTION ISOLATION LEVEL LEER SIN COMPROMISO

12

Utilizo SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDen la mayoría de mis consultas generales de SQL, principalmente porque esto me fue profundizado cuando aprendí el idioma originalmente.

Según tengo entendido, este nivel de aislamiento actúa de la misma manera que, WITH (NO LOCK)sin embargo, solo suelo usarlo SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED.

  • ¿Hay algún momento en el que debería estar usando WITH (NO LOCK)más SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED?
  • ¿ SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDImpide que otros usuarios se bloqueen de las tablas que estoy leyendo?
  • Si SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDse usa para detener las cerraduras, pero solo estoy leyendo datos, ¿cuál es el punto de usarlos? ¿Son solo las consultas intensivas del sistema las que generarían bloqueos? ¿Vale la pena usarlo cuando se ejecutan consultas que regresarían en unos 5-10 segundos?
  • Me han dicho que no use SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDcuando lea datos que se usarían en actualizaciones, presumiblemente para evitar actualizar datos sucios. ¿Sería esta la única razón?
  • Con el tipo de base de datos en la que estoy trabajando, hay un entorno de producción y prueba. Muy raramente consultaremos el entorno de producción, pero cuando sea necesario, generalmente lo usaré SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDen mi consulta. Entiendo que las lecturas sucias son posibles con esto. Además de recibir datos de vuelta que pueden no terminar comprometidos con la base de datos (y por lo tanto descartar mis resultados), ¿qué otros tipos de 'lecturas sucias' podrían ser posibles?

Perdón por las preguntas masivas.

dmoney
fuente
2
Podrías leer los mismos datos dos veces es otra caída de pozo. Usar RU o NO LOCK como estándar es una mala idea.
James Anderson
99
No usaría en READ UNCOMMITTEDtodas partes, exactamente de la misma manera que no usaría en WITH (NOLOCK)todas partes (son esencialmente lo mismo) blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere
Mark Sinkinson
1
Mire los modelos de aislamiento SNAPSHOT. Son mucho más fuertes que la UCR y tampoco bloquean ni causan bloqueo. Suenan como un buen modelo predeterminado para usted (¡en lugar de usar RCU de forma predeterminada!).
usr

Respuestas:

25

Es terrible que lo hayas aprendido de esa manera (¡perdón!).

READ UNCOMMITTEDvamos a leer cada fila, sí. Incluso aquellos que se utilizan actualmente en una INSERT, UPDATE, DELETEfuncionamiento. Esto es muy útil si necesita echar un vistazo rápido a algunos datos o en SELECTdeclaraciones de misión crítica donde un bloque sería muy dañino.

De hecho, arriesgas tu integridad. Puede ocurrir que lea una fila, que actualmente se usa para eliminar o en un cambio. También puede parecer que leyó un valor incorrecto. Esto puede ser realmente poco común, pero puede suceder. ¿Qué quiero decir con eso? Bueno, piense en una fila que es muy amplia (tiene muchas columnas con muchas columnas largas nvarchar). Se produce una actualización en esta fila y establece nuevos valores. En casos raros puede sucederle que lea solo media fila. Otra cosa puede suceder, por ejemplo, si un usuario cambia sus valores de inicio de sesión. Cambia su correo + contraseña. El correo ya está configurado, pero la contraseña no. De esta manera tienes un estado inconsistente.

Sugeriría olvidarlo READ UNCOMMITTED. Solo utilízalo donde sea realmente necesario.

Otra alternativa para usted puede ser habilitar la READ_COMMITTED_SNAPSHOTopción de base de datos; por lo tanto, puede usarla READ COMMITTED SNAPSHOTdebido al control de versiones de fila habilitado en su tempdb. De esta manera, solo lee otra versión (más antigua) de una fila. Esto no bloqueará sus consultas. Pero puede ocurrir que también lea un valor antiguo, pero un valor antiguo consistente.

Otra idea puede ser en WITH(READPAST)lugar de WITH(NOLOCK). Leerá el estado anterior de la tabla (un poco como en el SNAPSHOT ISOLATION), pero omitirá todas las filas bloqueadas actualmente.

Iónico
fuente
@ Ionic, muchas gracias por la respuesta! Realmente aprecio la ayuda en eso.
dmoney
@HingeSight, parece que sí, pero hay muchas posibilidades de que sea mi interpretación de la declaración, gracias de cualquier manera por su aporte.
dmoney
1
SNAPSHOT ISOLATIONno necesita estar habilitado para encender READ COMMITTED SNAPSHOT. Solo la READ COMMITTED SNAPSHOTopción de base de datos debe estar habilitada para que el control de versiones de la fila en lugar de bloquear la coherencia de lectura, evite la necesidad de lecturas sucias.
Dan Guzman
Sí, me refería a eso @DanGuzman. Lo siento, la respuesta fue un poco confusa en ese punto. Lo edité :-)
Ionic
Con READPAST omitirá los registros que están bloqueados, no obtendrá los valores antiguos, por lo que el único lugar que he descubierto que podría usarse es el manejo de colas
James Z
2

Como dice la respuesta aceptada, olvídate de usar el nivel de aislamiento READ UNCOMMITTED (excepto cuando realmente sea necesario) ya que corres el riesgo de leer datos incorrectos. Pero para responder el tercer punto en su pregunta, hay dos situaciones que encuentro útiles:

  1. Al escribir y probar paquetes SSIS de SQL Server, los pasos del paquete pueden incluirse en una transacción. Si está probando un paquete ejecutándolo paso a paso en el depurador SSIS, es posible que desee examinar las tablas mientras haya bloqueos en la tabla. El uso de SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED le permite usar SQL Server Manager Studio para examinar las tablas mientras se depura el paquete.

  2. En SQL Server Manager Studio, puede probar el código T-SQL envolviéndolo en una transacción para darle la opción de revertir los cambios. Por ejemplo, en una base de datos de prueba, es posible que desee restaurar los datos al estado inicial como parte de su prueba. Si está probando el código envuelto en la transacción y desea verificar las tablas bloqueadas mientras la transacción está en curso, puede usar SET TRANSACTION ISVELATION LEAD LEED UNCOMMITTED para examinar los valores en otra ventana.

Acepto que estos son usos bastante oscuros para READ UNCOMMITTED, pero los he encontrado útiles en un entorno de prueba.

Ubercoder
fuente
1

En la mayoría de las bases de datos, la gran mayoría de la actividad, incluso las inserciones, eliminaciones y actualizaciones, están fuera de las transacciones explícitas.

Claro, READ UNCOMMITTED(Lecturas sucias) puede proporcionar información incorrecta en estos casos, pero esa información fue correcta 5 segundos antes.

Los momentos en que las lecturas sucias producen resultados realmente malos son cuando una transacción falla y tiene que revertirse o cuando se ejecuta una consulta en dos tablas que normalmente se actualizan juntas mediante una transacción explícita.

Mientras tanto, en una base de datos típica grande y ocupada que tiene una proporción de 100 (o más) a 1 de lecturas a escrituras, CADA consulta individual (lectura) que no utiliza Dirty Reads está ralentizando el sistema porque necesita obtener y verificar para los bloqueos Y está haciendo que sea mucho más probable que las transacciones fallen (generalmente debido a puntos muertos), lo que puede causar problemas de integridad de la base de datos más graves.

En cambio, el uso de lecturas sucias hace que el sistema sea MUCHO más rápido y más confiable (en parte debido al rendimiento mejorado que hace que las inconsistencias sean menos probables).

Claro, hay momentos en que no deberían usarse. No me gusta configurar la base de datos por defecto para usar el READ UNCOMMITTEDnivel de aislamiento o incluso usar la SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDdeclaración explícita al comienzo de los Scripts SQL y los SP: hay demasiadas posibilidades de que ocurra una Lectura sucia cuando no debería. En cambio, las (NOLOCK)sugerencias son un enfoque mucho mejor ya que indican explícitamente que el programador pensó en lo que estaban haciendo y decidió que, para esta tabla específica en esta consulta específica, las lecturas sucias eran seguras.

Si está programando una aplicación para transferir dinero de una cuenta bancaria a otra, no debe usar Dirty Reads. Pero la mayoría de las aplicaciones no necesitan ese nivel de paranoia.

Simon Holzman
fuente