2010-10-15 8 views
5

Tengo una situación como esta.¿Qué nivel de aislamiento usar para evitar que se lean datos?

Consulta es como esto.

Select * from TABLE where ID = 1 

(lo que una consulta :)

después de que cambiar cosas en esa fila e insertarla con el nuevo ID.

Quiero evitar que otras consultas lean esa primera fila original desde consulta, hasta que termine la lectura y la inserción. Después de eso ... adelante.

Básicamente quiero seleccionar e insertar para estar en la transacción, con nivel de aislamiento que evitará la lectura solo desde esa fila hasta que finalice la inserción.

OleDbTransaction está en juego porque el uso de SQL Server 6.5 (oh, sí has ​​leído bien, no le pregunte por qué :)

que estaba cavando a través de la descripción niveles de aislamiento, pero no acabo de entender ellos y encontrar una solución para mi problema, entonces mi pregunta es ¿qué nivel de aislamiento usar para OleDbTransaction?

Espero que fuera claro :)

Gracias.

Respuesta

-1

Debe colocar un candado en la fila: cree el candado antes de leer la fila y suelte el candado después de haber actualizado la fila.

En Oracle y bases de datos similares, lee no bloquear, por lo que hay que hacer lo siguiente (en una transacción):

SELECT * FROM table WHERE id=? FOR UPDATE 
... 
UPDATE table .... 

En MS SQL, no estoy realmente seguro, la manera más fácil sería intentar lo siguiente: abrir dos ventanas conectadas a la base de datos, iniciar una transacción en ambas, hacer SELECCIONAR y ver si puede hacer la selección a partir del segundo. Si la declaración no regresa, eso significa que la fila está bloqueada y estás bien.

Asumo, en su pregunta, que significa a actualización la fila después de haber seleccionado que, no insertar situación que (inserción crea una nueva fila, actualización cambia una fila existente)

+0

respuesta inútil, porque el nivel de aislamiento básico en MS SQL es más flexible que uno en Oracle – Andrey

+0

-1 ¿Por qué respondiste para Oracle cuando es SQL Server, y luego mencionas que no lo haces? saberlo tampoco? – gbn

+0

En primer lugar, alguien en Internet podría encontrar esta página y utilizar Oracle, así que pensé que podría incluirlo; en segundo lugar, podría ser similar en SQL Server, por lo que podría ser un puntero en la dirección correcta. –

0

Descrito se llama Phantom Read. Por lo tanto, necesita aislamiento serializable (SERIALIZABLE)

+0

¿por qué esto fue downvoted? – Andrey

+0

Primero puse este nivel de aislamiento, y luego algunos otros, pero en todos los casos obtuve un error al decir que el proceso que ejecuta la misma consulta de selección queda atrapado en un punto muerto, y se convierte en víctima de interbloqueo y se cancela. Parece que esto con niveles de aislamiento no es mi solución o estoy haciendo algo mal ... – 100r

5

Debe mantener el bloqueo durante la transacción. Y exclusivamente también.

Ahora, no estoy seguro de las opciones correctas para SQL Server 6.5. no han trabajado con él, ya que, er, 199x

BEGIN TRAN 

--edit, changed to XLOCK, ROWLOCK, HOLDLOCK 
SELECT * from TABLE WITH (XLOCK, ROWLOCK, HOLDLOCK) where ID = 1 
... 
INSERT 

COMMIT 

Editar:

Mi cambio tiene como objetivo bloquear la hilera exclusivamente (con granularidad fina) hasta el final de la transacción .

Sin embargo, IIRC ROWLOCK se agregó con SQL Server 7 y 6.5 solo bloqueos de página. Pero ha pasado un tiempo. Tenía pelo y dientes en ese entonces :-)

+0

No debo usar el bloqueo de tabla. porque hay un queris muy pesado todo el tiempo, y TABLOCKX es un bloqueo de mesa ¿no? – 100r

+0

Consulte la actualización – gbn

+0

tnx. No podría hacer que ninguno de los bloqueos funcione. la consulta no compilará tal vez 6.5 sintax es diferente. Lo intentaré el lunes en el trabajo, gracias a Dios que no tengo 6.5 en casa :) – 100r

Cuestiones relacionadas