2012-01-09 14 views
5

Estoy trabajando en una aplicación multiproceso (C#), y 2 hilos están actualizando una tabla con NOLOCK al mismo tiempo, ¿es eso un problema? Para ser más específicos, ambos están actualizando los mismos registros.NOLOCK con multiprocesamiento

+3

Saber cuándo usar NOLOCK requiere una comprensión profunda de cómo, cuándo y por qué SQL Server bloquea qué. No debe usarse casualmente. Si tiene que hacer esta pregunta, probablemente no deba usar NOLOCK en absoluto. –

+1

¡NOLOCK ignora el bloqueo que tiene el escritor cuando solo quiere hacer una lectura sucia! –

+0

Si supiera sobre nolock, no preguntaría :) Así es como se implementó la aplicación en mi trabajo y estoy depurando el problema. Usan nolock en cada consulta independientemente. Tenemos casi 800 procs almacenados. – fbhdev

Respuesta

4

La respuesta es "depende".

NOLOCK permite 'lecturas sucias'. Esto significa que dentro de una transacción, es posible que vea datos no confirmados de otra transacción. Si tiene varios subprocesos actualizando la misma fila en la misma tabla, puede ver el valor modificado de los datos que tocó el otro subproceso, antes de que ese subproceso realice su transacción.

Por ejemplo, tome la tabla account_balances, definida como (account_num int, balance decimal (12,2)). Vamos a suponer que ocurre lo siguiente:

// precondición, cuenta # 1 tiene un saldo de 10,00

  1. Tema # 1 comienza una transacción, disminuye la cuenta # 1 por 10
  2. Tema # 2 se inicia una transacción , intenta leer el saldo de la cuenta n. ° 1. Se lee un saldo de 0.
  3. Tema # 2 decrementa la cuenta por $ 5, y emite un sobregiro al cliente (su equilibrio está -5)
  4. hilo # 1 rollos vuelta Es transacción
  5. Tema # 2 confirmaciones es transacción

// el saldo de la cuenta es ahora -5, a pesar de que debería ser 5.

lo que no se ver es algún tipo de datos inconsistentes dentro de un campo de la pista nolock no es como ejecutar código multihilo sin ti t un candado: las escrituras individuales siguen siendo atómicas.

+1

Incluso en 'read uncommitted', los escritores bloquean a los escritores. Por lo tanto, el hilo 2 no podría actualizar la fila hasta que se complete la transacción del hilo 1. Aparte de eso, esto es perfecto. – zinglon

+0

Reparado, gracias por la captura –

+0

Entonces, si estoy esperando un 1 en la columna y aparece como 2, ¿podría ser una carrera de subprocesos en lugar de tener nada que ver con nolock? – fbhdev

2

Significa que puede obtener registros que están en un estado 'erróneo'.

Por ejemplo ...

  • Process1 está borrando un bloque de datos
  • Proceso2 está leyendo un bloque de superposición de datos, CON NOLOCK

En una situación ideal, ya sea toda la registros eliminados por Process1 están presentes o eliminados. Como Process2 está utilizando NOLOCK, puede leer algunos de los registros que Process1 está eliminando, pero no otros porque ya se han ido.

Lo mismo aplica para INSERTOS y ACTUALIZACIONES. Simplemente puede leer los registros que están en parte alterados de alguna manera.


Si esto es un problema depende de sus datos, su diseño, etc.

Un motor de búsqueda no le importa si esto sucede. Un banco que se ocupe de las transcaciones financieras lo hará.

0

No puede cambiar la misma grabación simultáneamente, incluso si utiliza la sugerencia NOLOCK.

PERO

Usted puede llevar los datos en estado incoherente.

AFAIK - no es posible aplicar esta sugerencia a la tabla de actualización de destino.

Y - esta receta le permite leer datos no confirmados, no sobrescribir ellos.

0

Tenga cuidado de cómo utilizar esto. Posibles inconsistencias de datos.

Si uno consulta es establecer colA = "newColANewvalue" de la Tabla A mediante (nolock), donde colA = "colAOldvalue"

Y otra consulta es conjunto colC = "colCnewValue" de la Tabla A mediante (nolock), donde colA = "colAOldvalue"

Puede terminar con colC = "colCnewValue" y colA = "newColANewvalue" en el mismo registro. Si eso no es un problema, entonces está bien.

¿Qué está conduciendo esto? ¿Estás teniendo problemas de rendimiento con rowlock o pagelock?