Pregunta ¿Qué es "with (nolock)" en SQL Server?


¿Alguien puede explicar las implicaciones de usar with (nolock) en consultas, ¿cuándo 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 estaría bien? ¿Hay casos en que siempre debes usarlo / nunca usarlo?


526
2018-03-26 17:13


origen


Respuestas:


WITH (NOLOCK) es el equivalente a utilizar READ UNCOMMITED como nivel de aislamiento de transacción. Por lo tanto, corre el riesgo de leer una fila no confirmada que posteriormente se retrotrae, es decir, datos que nunca llegaron a la base de datos. Por lo tanto, aunque puede evitar que las lecturas se estanquen en otras operaciones, implica un riesgo. En una aplicación de banca con altas tasas de transacción, probablemente no sea la solución correcta para cualquier problema que intente resolver con él en mi humilde opinión.


383
2018-03-26 17:16



La pregunta es qué es peor:

  • un punto muerto, o
  • un valor equivocado?

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 transacciones DB es actualizar dos filas, restando de una y agregando a otra. Eso está mal.

En una base de datos financiera usa transacciones comerciales. Eso significa agregar una fila a cada cuenta. Es de suma importancia que estas transacciones se completen y las filas se escriban con éxito.

Conseguir que el saldo de la cuenta sea 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 debido a que se están utilizando dos cajeros automáticos a la vez que debido a una lectura no comprometida de una base de datos.

Dicho esto, SQL Server 2005 solucionó la mayoría de los errores que cometieron NOLOCK necesario. Entonces, a menos que esté usando SQL Server 2000 o anterior, no debería necesitarlo.

Otras lecturas
Versiones a nivel de fila


152
2018-03-26 18:08



El ejemplo de libro de texto para el uso legítimo de la pista nolock es el muestreo de informe en una base de datos OLTP de actualización alta.

Para tomar un ejemplo tópico. Si un gran banco estadounidense de la calle quería realizar un informe por hora en busca de las primeras señales de un nivel de ciudad en el banco, una consulta de nolock podría escanear tablas de transacciones sumando depósitos en efectivo y retiros de efectivo por ciudad. Para dicho informe, el pequeño porcentaje de error causado por las transacciones de actualización retrasadas no reduciría el valor del informe.


48
2018-03-26 17:55



Lamentablemente, no solo se trata 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. Entonces sus resultados pueden ser groseramente sesgados.

Revisa Artículo de Itzik Ben-Gan. Aquí hay un extracto:

"Con la sugerencia NOLOCK (o configurar el   nivel de aislamiento de la sesión para LEER   NO COMPROMETIDO) le dices a SQL Server que   no esperas coherencia, entonces   no hay garantías. Sin embargo, ten en cuenta   que los "datos inconsistentes" no solo   significa que es posible que vea sin compromiso   cambios que luego fueron revertidos,   o cambios de datos en un intermediario   estado de la transacción También   significa que en una simple consulta que   escanea todos los datos de tabla / índice SQL Server   puede perder la posición de escaneo, o usted   podría terminar obteniendo la misma fila   dos veces. "


47
2018-03-29 07:30



No estoy seguro de por qué no está envolviendo las transacciones financieras en las transacciones de la base de datos (como cuando transfiere fondos de una cuenta a otra; no compromete un lado de la transacción a la vez; esta es la razón por la cual existen transacciones explícitas). Incluso si su código está loco por las transacciones comerciales como suena, 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 las versiones y limpie su código.

Ningún bloqueo no solo devuelve valores erróneos, sino que devuelve registros fantasma y duplicados.

Es un concepto erróneo común que siempre hace que las consultas se ejecuten más rápido. Si no hay bloqueos de escritura en una tabla, no hace ninguna 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 los bloqueos en primer lugar.

Para ser justos, aquí hay dos escenarios especiales donde una pista de nolock puede proporcionar utilidad

1) Base de datos de servidor sql anterior a 2005 que necesita ejecutar una consulta larga en base de datos OLTP en vivo. Esta puede ser la única forma.

2) Aplicación mal escrita que bloquea los 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 (de un tercero, etc.) y la base de datos es anterior a 2005 o no se puede activar el control de versiones.


30
2018-03-03 17:01



NOLOCK es equivalente a READ UNCOMMITTED, sin embargo, Microsoft dice que no debe usarlo para UPDATE o DELETE declaraciones:

Para las sentencias UPDATE o DELETE: esta característica se eliminará en una versión futura de Microsoft SQL Server. Evite usar esta característica en nuevos trabajos de desarrollo y planee modificar las aplicaciones que actualmente usan esta característica.

http://msdn.microsoft.com/en-us/library/ms187373.aspx

Este artículo se aplica a SQL Server 2005, por lo que el soporte para NOLOCK existe si estás usando esa versión. Para poder proteger 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


23
2018-03-26 17:43



Otro caso en el que generalmente está bien es en una base de datos de informes, donde los datos quizás ya están envejecidos y las escrituras simplemente no ocurren. Sin embargo, en este caso, el administrador debe establecer la opción en la base de datos o en la tabla cambiando el nivel de aislamiento predeterminado.

En el caso general: puedes usarlo cuando estás muy Seguro que está bien leer datos viejos. Lo importante para recordar es que es es muy fácil equivocarse. Por ejemplo, incluso si está bien en el momento de escribir la consulta, ¿está seguro de que algo no cambiará en la base de datos en el futuro para que estas actualizaciones sean más importantes?

También voy a la 2da noción de que es probable no una buena idea en la aplicación de banca O la aplicación de inventario. O en cualquier lugar en el que pienses sobre transacciones.


15
2018-03-26 17:19