¿Alguien puede explicar las implicaciones del uso with (nolock)
en consultas, cuando debería / no debería usarlo?
Por ejemplo, si tiene una aplicación bancaria con altas tasas de transacción y una gran cantidad de datos en ciertas tablas, ¿en qué tipos de consultas nolock estaría bien? ¿Hay casos en los que siempre debe usarlo / nunca usarlo?
sql-server
nolock
Andy White
fuente
fuente
Respuestas:
WITH (NOLOCK) es el equivalente a usar READ UNCOMMITED como nivel de aislamiento de transacción. Por lo tanto, corre el riesgo de leer una fila no confirmada que se revierte posteriormente, es decir, datos que nunca llegaron a la base de datos. Por lo tanto, aunque puede evitar que otras operaciones bloqueen las lecturas, conlleva un riesgo. En una aplicación bancaria con altas tasas de transacción, probablemente no será la solución correcta para cualquier problema que intente resolver con mi en mi humilde opinión.
fuente
NOLOCK
con unSELECT
, corre el riesgo de devolver las mismas filas más de una vez (datos duplicados) si alguna vez se insertan (o actualizan) datos en la tabla al hacer una selección.La pregunta es qué es peor:
Para las bases de datos financieras, los puntos muertos son mucho peores que los valores incorrectos. Sé que suena al revés, pero escúchame. El ejemplo tradicional de las transacciones de DB es que actualiza dos filas, restando de una y sumando a otra. Eso está mal.
En una base de datos financiera, utiliza transacciones comerciales. Eso significa agregar una fila a cada cuenta. Es de suma importancia que estas transacciones se completen y que las filas se escriban con éxito.
Obtener el saldo de la cuenta temporalmente incorrecto no es un gran problema, para eso sirve la reconciliación al final del día. Y es mucho más probable que ocurra un sobregiro de una cuenta porque se usan dos cajeros automáticos a la vez que debido a una lectura no confirmada de una base de datos.
Dicho esto, SQL Server 2005 corrigió la mayoría de los errores que hacía
NOLOCK
necesarios. Entonces, a menos que esté utilizando SQL Server 2000 o anterior, no debería necesitarlo.Lecturas adicionales
de versiones de nivel de fila
fuente
Lamentablemente, no se trata solo de leer datos no confirmados. En segundo plano, puede terminar leyendo páginas dos veces (en el caso de una división de página), o puede perder las páginas por completo. Por lo tanto, sus resultados pueden ser muy sesgados.
Mira el artículo de Itzik Ben-Gan . Aquí hay un extracto:
fuente
El ejemplo de libro de texto para el uso legítimo de la sugerencia nolock es el muestreo de informes en una base de datos OLTP de alta actualización.
Para tomar un ejemplo tópico. Si un gran banco de la calle de los EE. UU. Quisiera realizar un informe por hora buscando los primeros signos de una ejecución a nivel de ciudad en el banco, una consulta nolock podría escanear tablas de transacciones que sumen depósitos de efectivo y retiros de efectivo por ciudad. Para dicho informe, el pequeño porcentaje de error causado por las transacciones de actualización revertidas no reduciría el valor del informe.
fuente
No estoy seguro de por qué no está envolviendo transacciones financieras en transacciones de bases de datos (como cuando transfiere fondos de una cuenta a otra, no compromete un lado de la transacción a la vez, es por eso que existen transacciones explícitas). Incluso si su código es un cerebro inteligente para las transacciones comerciales como parece, todas las bases de datos transaccionales tienen el potencial de hacer retrocesos implícitos en caso de errores o fallas. Creo que esta discusión está muy por encima de tu cabeza.
Si tiene problemas de bloqueo, implemente el control de versiones y limpie su código.
Sin bloqueo no solo devuelve valores incorrectos, devuelve registros fantasma y duplicados.
Es un error común pensar que siempre hace que las consultas se ejecuten más rápido. Si no hay bloqueos de escritura en una tabla, no hay diferencia. Si hay bloqueos en la tabla, puede hacer que la consulta sea más rápida, pero hay una razón por la cual se inventaron bloqueos en primer lugar.
Para ser justos, aquí hay dos escenarios especiales donde una sugerencia de nolock puede proporcionar utilidad
1) La base de datos del servidor SQL anterior a 2005 que necesita ejecutar una consulta larga contra la base de datos OLTP en vivo, esta puede ser la única forma
2) La aplicación mal escrita que bloquea registros y devuelve el control a la interfaz de usuario y los lectores se bloquean indefinidamente. Nolock puede ser útil aquí si la aplicación no se puede arreglar (terceros, etc.) y la base de datos es anterior a 2005 o no se puede activar el control de versiones.
fuente
NOLOCK
es equivalente aREAD UNCOMMITTED
, sin embargo, Microsoft dice que no debe usarloUPDATE
oDELETE
declaraciones:http://msdn.microsoft.com/en-us/library/ms187373.aspx
Este artículo se aplica a SQL Server 2005, por lo que la compatibilidad
NOLOCK
existe si está utilizando esa versión. Para preparar su código en el futuro (suponiendo que haya decidido usar lecturas sucias), puede usar esto en sus procedimientos almacenados:SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
fuente
Puede usarlo cuando solo está leyendo datos, y realmente no le importa si podría o no recuperar datos que aún no se han confirmado.
Puede ser más rápido en una operación de lectura, pero realmente no puedo decir cuánto.
En general, recomiendo no usarlo: leer datos no confirmados puede ser un poco confuso en el mejor de los casos.
fuente
Otro caso en el que generalmente está bien es en una base de datos de informes, donde los datos tal vez ya están obsoletos y las escrituras simplemente no suceden. Sin embargo, en este caso, el administrador debe establecer la opción en el nivel de la base de datos o la tabla cambiando el nivel de aislamiento predeterminado.
En el caso general: puede usarlo cuando esté muy seguro de que está bien leer datos antiguos. Lo importante para recordar es que es muy fácil equivocarse . Por ejemplo, incluso si está bien al momento de escribir la consulta, ¿está seguro de que algo no cambiará en la base de datos en el futuro para hacer que estas actualizaciones sean más importantes?
También voy a la segunda idea de que probablemente no sea una buena idea en la aplicación bancaria. O aplicación de inventario. O en cualquier lugar donde esté pensando en transacciones.
fuente
Respuesta simple: cuando su SQL no está alterando los datos, y tiene una consulta que podría interferir con otra actividad (mediante bloqueo).
Vale la pena considerar cualquier consulta utilizada para los informes, especialmente si la consulta lleva más de, por ejemplo, 1 segundo.
Es especialmente útil si tiene informes de tipo OLAP que está ejecutando en una base de datos OLTP.
Sin embargo, la primera pregunta es "¿por qué me preocupo por esto?" En mi experiencia, eludir el comportamiento de bloqueo predeterminado a menudo ocurre cuando alguien está en modo "probar cualquier cosa" y este es un caso donde las consecuencias inesperadas no son improbables. Con demasiada frecuencia es un caso de optimización prematura y puede quedar fácilmente incrustado en una aplicación "por si acaso". Es importante entender por qué lo está haciendo, qué problema resuelve y si realmente tiene el problema.
fuente
Respuesta corta:
Solo se usa
WITH (NOLOCK)
en la instrucción SELECT en tablas que tienen un índice agrupado.Respuesta larga:
WITH (NOLOCK) a menudo se explota como una forma mágica de acelerar las lecturas de la base de datos.
El conjunto de resultados puede contener filas que aún no se han confirmado, que a menudo se deshacen más tarde.
Si WITH (NOLOCK) se aplica a una tabla que tiene un índice no agrupado, las transacciones pueden cambiar los índices de fila a medida que los datos de la fila se transmiten a la tabla de resultados. Esto significa que al conjunto de resultados pueden faltar filas o mostrar la misma fila varias veces.
READ COMMITTED agrega un problema adicional en el que los datos se corrompen dentro de una sola columna donde varios usuarios cambian la misma celda simultáneamente.
fuente
READ UNCOMITTED
no lo afectará en absoluto. Hay una razón por la que se incluyó en el estándar ANSI.Mis 2 centavos, tiene sentido usar
WITH (NOLOCK
) cuando necesita generar informes. En este punto, los datos no cambiarían mucho y no querría bloquear esos registros.fuente
Si está manejando transacciones financieras, nunca querrá usarlas
nolock
.nolock
se utiliza mejor para seleccionar de tablas grandes que tienen muchas actualizaciones y no le importa si el registro que obtiene podría estar desactualizado.Los registros financieros (y casi todos los demás registros en la mayoría de las aplicaciones)
nolock
causarían estragos, ya que potencialmente podría leer los datos de un registro que se estaba escribiendo y no obtener los datos correctos.fuente
Solía recuperar un "próximo lote" para hacer cosas. No importa en este caso qué elemento exacto, y tengo muchos usuarios ejecutando esta misma consulta.
fuente
Use nolock cuando esté de acuerdo con los datos "sucios". Lo que significa que nolock también puede leer datos que están en proceso de modificación y / o datos no confirmados.
En general, no es una buena idea usarlo en un entorno de alta transacción y es por eso que no es una opción predeterminada en la consulta.
fuente
Utilizo con (nolock) sugerencia particularmente en bases de datos SQLServer 2000 con alta actividad. Sin embargo, no estoy seguro de que sea necesario en SQL Server 2005. Recientemente agregué esa sugerencia en un SQL Server 2000 a pedido del DBA del cliente, porque notó muchos bloqueos de registros SPID.
Todo lo que puedo decir es que usar la pista NO nos ha hecho daño y parece haber hecho que el problema de bloqueo se resuelva por sí solo. El DBA en ese cliente en particular básicamente insistió en que usáramos la pista.
Por cierto, las bases de datos con las que trato son back-end de los sistemas empresariales de reclamaciones médicas, por lo que estamos hablando de millones de registros y más de 20 tablas en muchas combinaciones. Normalmente agrego una sugerencia WITH (nolock) para cada tabla en la unión (a menos que sea una tabla derivada, en cuyo caso no puede usar esa sugerencia en particular)
fuente
La respuesta más simple es una pregunta simple: ¿necesita que sus resultados sean repetibles? En caso afirmativo, NOLOCKS no es apropiado bajo ninguna circunstancia
Si no necesita repetibilidad, los nolocks pueden ser útiles, especialmente si no tiene control sobre todos los procesos que se conectan a la base de datos de destino.
fuente