La mejor situación para usar LEER Nivel de aislamiento NO COMPROMETIDO

10

Como todos sabemos, LEER NO COMPROMETIDO es el nivel de aislamiento más bajo en el que se pueden acumular cosas como lecturas sucias y lecturas fantasmas. ¿Cuándo es el mejor momento para usar este nivel de aislamiento y por qué razones podría usarse?

En realidad, leí las respuestas antes, pero no pude entenderlo completamente porque no había suficientes ejemplos.

Peter Mortensen
fuente

Respuestas:

20

Uso READ_UNCOMMITTED(o NOLOCK) cuando consulto bases de datos de producción desde SSMS pero no de forma rutinaria desde el código de la aplicación. Esta práctica (junto con una sugerencia de consulta MAXDOP 1) ayuda a garantizar que las consultas casuales para el análisis de datos y la resolución de problemas no afecten la carga de trabajo de producción, con la comprensión de que los resultados pueden no ser correctos.

Lamentablemente, veo READ_UNCOMMITTED/ NOLOCKuso ampliamente en el código de producción para evitar el bloqueo a expensas de la integridad de los datos. La solución adecuada es un nivel de aislamiento de versiones de fila ( SNAPSHOTo READ_COMMITTEDcon la READ_COMMITTED_SNAPSHOTopción de base de datos ON) y / o atención a consultas y ajuste de índice.

Recientemente revisé el código de un proceso en el que el único cambio era eliminarlo NOLOCKporque a veces arrojaba resultados incorrectos. La eliminación NOLOCKfue algo bueno, pero, sabiendo que las filas perdidas o duplicadas generalmente ocurren durante los escaneos de orden de asignación de tablas grandes, sugerí también refactorizar para usar una UNION ALLtécnica para promover el uso eficiente del índice. La consulta ahora se ejecuta en unos pocos milisegundos con resultados correctos, el mejor de todos los mundos.

Dan Guzman
fuente
7

Creo que está bien en algunas circunstancias, siempre que acepte las consecuencias y no tenga otras opciones.

Para otras opciones, empujaría a las personas a usar el aislamiento de instantáneas de lectura comprometida (RCSI) para nuevas aplicaciones, o la AISLAMIENTO DE INSTANTÁNEA (SI) para aplicaciones más antiguas, donde no se puede probar fácilmente la base de código completa para las condiciones de carrera con RCSI.

Sin embargo, esos podrían no ser una buena opción. Es posible que necesite pasar un tiempo extra amando y cuidando tempdb, y asegurándose de que nadie deje una transacción abierta que haga que la tienda de versiones (y tempdb) crezca y llene el disco.

Si no tiene un DBA, o alguien cuyo trabajo es monitorear y administrar su SQL Server, esas opciones pueden ser peligrosas. En términos más generales, no todos tienen el control total del código que va a su servidor, donde pueden cambiar la cadena de conexión o el código para solicitar SI si hay consultas problemáticas.

Además de eso, la mayoría de las personas no tienen problemas de bloqueo con toda su aplicación . Tienen problemas con cosas como informar sobre datos OLTP. Si puede aceptar las compensaciones de NOLOCK / RU a cambio de que los informes no sean bloqueados por los escritores, hágalo.

Solo asegúrate de entender lo que eso significa. No significa que su consulta no tenga bloqueos, significa que no respeta los bloqueos extraídos por otras consultas.

Y, por supuesto, si su problema es el bloqueo escritor / escritor, la única opción que ayudará es SI, pero se necesitaría una increíble cantidad de trabajo del desarrollador para implementarlo adecuadamente con el manejo de errores, etc.

Erik Darling
fuente
55
Y si el problema realmente es simplemente informar sobre datos OLTP, descárguelo a un secundario de solo lectura de algún tipo (AG, envío de registros, replicación o roll-your-own).
Aaron Bertrand
3
@AaronBertrand Y luego tendrían un segundo servidor para monitorear;)
Erik Darling
5

En mi humilde opinión, el único caso de uso válido para READ UNCOMMITTED en un sistema moderno es cuando depura una sesión de otra en desarrollo, para que pueda ver lo que está haciendo mientras, por ejemplo, un proceso almacenado todavía se está ejecutando. Nunca se utilizaría normalmente en un sistema de producción. Puede haber una ganancia de rendimiento menor, pero a largo plazo nunca valdrá la pena.

Gayo
fuente
3

Lo usamos en el cuidado de la salud todo el tiempo.

Es asombrosamente raro que las filas individuales de datos cambien a mitad de la consulta, y la relación de lectura / escritura es como 10,000 / 1, y la mayoría de ellas son inserciones, no actualizaciones. Por ejemplo, cuando la interfaz de laboratorio escribe los resultados de laboratorio de un paciente en la base de datos, esos valores nunca cambiarán.

Cuando los datos lo hace el cambio, cambia una fila a la vez. Nadie está actualizando columnas enteras (excepto un DBA, cuando se equivocan realmente).

Por otro lado, ejecutamos un montón de consultas para buscar cosas como pacientes que regresan a la sala de emergencias en 72 horas o menos, lo que afecta las mesas.

En 10 años de SQL de atención médica, nunca he visto a Rollback Transaction. Quiero entrar y salir sin interrumpir la experiencia del usuario final. Si existe un alto riesgo de ralentizar la base de datos OLTP y un bajo riesgo de obtener datos incorrectos, NOLOCK.

¿ Deberíamos usarlo? Tal vez tal vez no. En términos generales, no diría que muchas de las bases de datos de aplicaciones en las que he trabajado están bien diseñadas. Normalmente están llenos de antipatrones.

James
fuente
44
solo para su información, es posible leer filas parcialmente escritas con nolock.
Max Vernon
1
Oof! Realmente necesito que mi jefe me compre otro servidor para poder registrar este envío ...
James
3
Puede que le interese esta ingeniosa publicación de blog de Paul White sobre LEER SIN COMPROMISO, especialmente la sección "Leer datos corruptos": El nivel de aislamiento de lectura no comprometida
Josh Darnell
1

READ_UNCOMMITTED/NOLOCKes una buena opción cuando la precisión de los datos no es realmente el objetivo principal. A veces, cuando un recuento agregado aproximado es todo lo que se requiere. Por ejemplo: hay procedimientos almacenados que se utilizan para INSERTAR o ACTUALIZAR tablas. A veces, la cantidad de registros que se deben actualizar o insertar es enorme (Miles de registros). Durante estas ejecuciones de procedimientos almacenados, podemos ejecutar NOLOCKperiódicamente una consulta de selección simple en la tabla de destino para ver si progresa sin problemas (para la consulta de actualización, si tiene una columna de cambio de estado para los registros que se actualizan, podemos usar esa columna para ejecutar la group byconsulta con NOLOCKpara averiguar si el recuento de cambios de estado cambia constantemente).

GirKarr
fuente
0

Tenga en cuenta que READ UNCOMMITTED presenta problemas de coherencia adicionales, no solo lecturas sucias. Dependiendo del método de acceso, puede perder filas o incluso leer la misma fila más de una vez. Si está interesado en los detalles, lea el artículo de Itzik Ben-Gan

SQLRaptor
fuente
3
Faltan filas y leen filas más de una vez, también es posible en el nivel predeterminado de lectura confirmada. Si una columna de clave de índice se actualiza durante el escaneo y se mueve.
Martin Smith
La discusión paralela sobre esta respuesta se ha movido al chat .
Paul White 9