sql server - transaction - ¿Por qué usar un nivel de aislamiento READ UNCOMMITTED?
sql read uncommitted (10)
¿Cuándo está bien usar READ UNCOMMITTED
?
Regla de oro
Bueno : grandes informes agregados que muestran totales en constante cambio.
Risky : Casi todo lo demás.
La buena noticia es que la mayoría de los informes de solo lectura se encuentran en esa categoría de Buena .
Mas detalle...
Ok para usarlo:
- Casi todos los informes agregados de cara al usuario para datos actuales y no estáticos, p. Ej., Ventas anuales. Se corre el riesgo de un margen de error (tal vez <0.1%) que es mucho menor que otros factores de incertidumbre, como el error de entrada o simplemente la aleatoriedad de cuándo los datos exactos se registran minuto a minuto.
Eso cubre probablemente la mayoría de lo que haría un departamento de Business Intelligence en, por ejemplo, SSRS. La excepción, por supuesto, es cualquier cosa con signos de $ delante. Muchas personas representan el dinero con mucho más entusiasmo que lo que se aplica a las métricas básicas relacionadas necesarias para atender al cliente y generar ese dinero. (Culpo a los contadores).
Cuando arriesgado
Cualquier informe que baje al nivel de detalle. Si se requiere ese detalle, generalmente implica que cada fila será relevante para una decisión. De hecho, si no puede extraer un pequeño subconjunto sin bloquearlo, es posible que se esté editando actualmente.
Información histórica. Rara vez hace una diferencia práctica, pero si bien los usuarios entienden que los datos que cambian constantemente no pueden ser perfectos, no sienten lo mismo con los datos estáticos. Las lecturas sucias no duelen aquí, pero las lecturas dobles pueden ser ocasionales. Al ver que no debería tener bloques en datos estáticos, ¿por qué arriesgarse?
Casi todo lo que alimenta una aplicación que también tiene capacidades de escritura.
Cuando incluso el escenario OK no está bien.
- ¿Hay alguna aplicación o proceso de actualización que haga uso de grandes transacciones individuales? ¿Los que se eliminan y luego vuelven a insertar muchos registros sobre los que informa? En ese caso, realmente no puedes usar
NOLOCK
en esas tablas para nada.
En un lenguaje sencillo, ¿cuáles son las desventajas y ventajas de usar
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
en una consulta para aplicaciones .NET y aplicaciones de servicios de informes?
Con respecto a los informes, lo usamos en todas nuestras consultas de informes para evitar que una consulta se atasque en las bases de datos. Podemos hacerlo porque estamos obteniendo datos históricos, no datos actualizados en microsegundos.
Este nivel de aislamiento permite lecturas sucias. Una transacción puede ver cambios no confirmados realizados por alguna otra transacción.
Para mantener el nivel más alto de aislamiento, un DBMS generalmente adquiere bloqueos en los datos, lo que puede resultar en una pérdida de concurrencia y una alta sobrecarga de bloqueo. Este nivel de aislamiento relaja esta propiedad.
Si lo desea, puede consultar el artículo de Wikipedia sobre READ UNCOMMITTED
para ver algunos ejemplos y leer más.
También puede interesarle consultar el artículo del blog de Jeff Atwood sobre cómo él y su equipo abordaron un problema de interbloqueo en los primeros días de . Según Jeff:
Pero es
nolock
peligroso? ¿Podrías terminar leyendo datos no válidos conread uncommitted
? Sí, en teoría. No encontrará ninguna escasez de astronautas de arquitectura de base de datos que comiencen a dejar caer la ciencia de ACID y todos ellos activarán la alarma contra incendios del edificio cuando les diga que quieren probarnolock
. Es cierto: la teoría da miedo. Pero esto es lo que pienso: "En teoría, no hay diferencia entre la teoría y la práctica. En la práctica existe".Nunca recomendaría el uso de
nolock
como unanolock
general al problema del aceite de serpiente "bueno para lo que le aqueja" para cualquier problema de bloqueo de base de datos que pueda tener. Debes intentar diagnosticar la fuente del problema primero.Pero, en la práctica, agregar
nolock
a las consultas que usted sabe que son simples, los asuntos de solo lectura directos nunca parecen generar problemas ... Siempre que sepa lo que está haciendo.
Una alternativa al nivel READ UNCOMMITTED
que usted puede considerar es el READ COMMITTED SNAPSHOT
. Citando a Jeff de nuevo:
Las instantáneas se basan en un método de seguimiento de cambios de datos completamente nuevo ... más que un simple cambio lógico, requiere que el servidor maneje los datos físicamente de manera diferente. Una vez que se habilita este nuevo método de seguimiento de cambios de datos, se crea una copia o una instantánea de cada cambio de datos. Al leer estas instantáneas en lugar de datos en vivo en momentos de contención, los bloqueos compartidos ya no son necesarios en las lecturas, y el rendimiento general de la base de datos puede aumentar.
Esto le dará lecturas sucias y le mostrará las transacciones que aún no se han confirmado. Esa es la respuesta más obvia. No creo que sea una buena idea usar esto solo para acelerar tus lecturas. Hay otras formas de hacerlo si utiliza un buen diseño de base de datos.
También es interesante observar lo que no está sucediendo. READ UNCOMMITTED no solo ignora otros bloqueos de tabla. Tampoco está causando ningún bloqueo en su propio.
Considere que está generando un informe grande, o está migrando datos de su base de datos utilizando una declaración SELECT grande y posiblemente compleja. Esto causará un bloqueo compartido que puede escalarse a un bloqueo de tabla compartido durante la duración de su transacción. Otras transacciones pueden leerse de la tabla, pero las actualizaciones son imposibles. Esto puede ser una mala idea si es una base de datos de producción, ya que la producción puede detenerse por completo.
Si está utilizando READ UNCOMMITTED, no establecerá un bloqueo compartido en la tabla. Puede obtener el resultado de algunas transacciones nuevas o puede que no, dependiendo de en qué lugar de la tabla se insertaron los datos y cuánto tiempo se ha leído su transacción SELECT. También puede obtener los mismos datos dos veces si, por ejemplo, se produce una división de página (los datos se copiarán en otra ubicación en el archivo de datos).
Por lo tanto, si es muy importante para usted que los datos se puedan insertar mientras hace su SELECCIONAR, LEER NO COMPROMETIDO puede tener sentido. Debe tener en cuenta que su informe puede contener algunos errores, pero si se basa en millones de filas y solo algunos de ellos se actualizan al seleccionar el resultado, esto puede ser "suficientemente bueno". Su transacción también puede fallar en conjunto ya que la singularidad de una fila puede no estar garantizada.
Una mejor manera de hacerlo es utilizar SNAPSHOT ISOLATION LEVEL, pero sus aplicaciones pueden necesitar algunos ajustes para usarlo. Un ejemplo de esto es si su aplicación tiene un bloqueo exclusivo en una fila para evitar que otros lo lean y entren en modo de edición en la interfaz de usuario. SNAPSHOT ISOLATION LEVEL también viene con una penalización de rendimiento considerable (especialmente en el disco). Pero puedes superar eso lanzando hardware sobre el problema. :)
También puede considerar restaurar una copia de seguridad de la base de datos para usarla para informar o cargar datos en un almacén de datos.
Esto puede ser útil para ver el progreso de las consultas de inserción largas, realizar estimaciones aproximadas (como COUNT(*)
o SUM(*)
), etc.
En otras palabras, los resultados que devuelven las consultas de lectura incorrecta están bien siempre que los trate como estimaciones y no tome decisiones críticas basadas en ellas.
La ventaja es que puede ser más rápido en algunas situaciones. La desventaja es que el resultado puede ser incorrecto (los datos que aún no se han confirmado podrían devolverse) y no hay garantía de que el resultado sea repetible.
Si te importa la precisión, no uses esto.
Más información está en MSDN :
Implementa lectura sucia o bloqueo de nivel 0 de aislamiento, lo que significa que no se emiten bloqueos compartidos y que no se respetan los bloqueos exclusivos. Cuando se configura esta opción, es posible leer datos no confirmados o sucios; los valores en los datos se pueden cambiar y las filas pueden aparecer o desaparecer en el conjunto de datos antes del final de la transacción. Esta opción tiene el mismo efecto que configurar NOLOCK en todas las tablas en todas las declaraciones SELECT en una transacción. Este es el menos restrictivo de los cuatro niveles de aislamiento.
Mi caso de uso favorito para read uncommited
es depurar algo que está sucediendo dentro de una transacción.
Inicie su software bajo un depurador, mientras recorre las líneas de código, abre una transacción y modifica su base de datos. Mientras el código está detenido, puede abrir un analizador de consultas, establecer el nivel de aislamiento de lectura no confirmada y realizar consultas para ver qué está sucediendo.
También puede usarlo para ver si los procedimientos de ejecución prolongada se atascan o actualizan correctamente su base de datos.
Es genial si a su empresa le encanta realizar procedimientos almacenados demasiado complejos.
Se puede usar para una tabla simple, por ejemplo, en una tabla de auditoría de solo inserción, donde no hay actualización de la fila existente, y no hay fk para otra tabla. El inserto es un inserto simple, que tiene poca o ninguna posibilidad de retroceso.
Siempre uso READ UNCOMMITTED ahora. Es rápido con los menos problemas. Cuando utilice otros aislamientos, casi siempre se encontrará con algunos problemas de bloqueo.
Siempre y cuando use los campos de Incremento automático y preste un poco más de atención a las inserciones, entonces podrá pagar adiós a los problemas de bloqueo.
Puede cometer errores con LEER SIN COMPROMISO pero, para ser honesto, es muy fácil asegurarse de que sus inserciones sean una prueba completa. Las inserciones / actualizaciones que utilizan los resultados de una selección son solo una cosa que debe tener en cuenta. (Use LEER COMPROMETIDO aquí, o asegúrese de que las lecturas sucias no causen un problema)
Así que vaya a las Lecturas sucias (Especialmente para grandes informes), su software se ejecutará mejor ...
Use READ_UNCOMMITTED en una situación en la que es muy poco probable que cambie la fuente.
- Al leer datos históricos. por ejemplo, algunos registros de implementación que sucedieron hace dos días.
- Al leer metadatos de nuevo. Ej. Aplicación basada en metadatos.
No use READ_UNCOMMITTED cuando sepa que la fuente puede cambiar durante la operación de recuperación.