urgente: set transaction isolation level serializable

25/04/2004 - 10:25 por Víctor | Informe spam
Hola a tod@s.

Al ejecutarse un SP que tengo, lo primero que hace es leer los campos de una
tabla (A).
Luego empieza a leer campos de otras tablas y realizar inserts, y por último
actualiza la tabla (A).

Necesito que desde que lee A hasta que lo actualiza, nadie pueda acceder a
esta tabla (bueno, al menos a la fila que el SP ha leido), pues esta tabla
la utilizo como contador de facturas.

Lo que hice era primero de todo poner BEGIN TRAN, y al final un COMMIT TRAN,
y por en medio, si algo fallaba, un ROLLBACK TRAN.

Y hasta ahora (4 añitos) todo ha ido perfecto, pero la semana pasada se me
repitieron dos números de facturas :-(

No se qué ha podido pasar.

Ahora he puesto, antes del BEGIN TRAN, un SET TRANSACTION ISOLATION LEVEL
SERIALIZABLE.

¿Me servirá para algo o con el BEGIN TRAN ya me hes suficiente y el problema
es otro?

Muchas gracias.

Preguntas similare

Leer las respuestas

#6 Javier Loria
26/04/2004 - 13:56 | Informe spam
Hola Victor:
Todavia no se exactamente como estas haciendo el proceso, pero si lees y
luego actualizas, que es bastante "natural", es posible que entre uno y otro
exista modificacion.
Las alternativas (sin usar el ISOLATION LEVEL) son primero actualizar y
luego leer; o Actualizar y Leer al mismo tiempo.
Ejemplos:
=-- En 1 Paso
UPDATE Contadores
SET Valor=Valor+1
WHERE Concepto='SiguienteFactura'
SELECT @NumFactura=Valor
FROM Contadores
WHERE Concepto='SiguienteFactura'
UPDATE Contadores
SET @NumFactura=Valor=Valor+1
WHERE Concepto='SiguienteFactura'
= El ultimo me lo enseno Adrian Garcia.

Saludos,

Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.
Víctor escribio:
Ostras. Pues he tenido mucha suerte estos años, pues las facturas a
las que me refiero son billetes, y en el momento de un embarque hay
varios usuarios a la vez.

Vale, entonces, ¿hay alguna manera de "bloquear" una tabla durante
toda la ejecución de un SP?

Quitaría el ISOLATION LEVEL SERIALIZABLE, dejaría el BEGIN/COMMIT, y
sólo bloquearía la tabla de contadores. ¿Se puede?

"Javier Loria" escribió en el mensaje
news:
Hola:
Un BEGIN TRAN/COMMIT TRAN sin fijar el nivel de INSOLATION LEVEL
usara el nivel mas bajo permitido de SQL, que significa que leeras
unicamente registros commit, pero siempre estaras sujeto a otros
posibles errores, los mas conocidos son
a) Lecturas no Repetibles o sea que haces 2 Select iguales con
resultados diferentes, ya que entre el primero y el segundo
cambiaron datos que no estaban COMMIT en el primer SELECT y si lo
estaban en el segundo. b) Fantasmas: Insercion o Borrado de
Filas. Igual que el anterior pero con Insert/Delete.
En tu caso (sin ver ni una linea de codigo) es muy probable que
sea un problema del Fantasmas.
El que la tabla aparezca con bloqueo X, no necesariamente
significa que fue bien asignado el Numero, podria ocurrir que entre
la lectura y la escritura (que siempre bloquea) se produzcan
cambios, y que estes viendo el bloqueo Exclusivo de la Insercion NO
de la Lectura. :( Saludos,

Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.


Víctor escribio:
Pero con el BEGIN TRAN/COMMIT TRAN, ¿no se bloquean las tablas
durante todo el SP?

Me he fijado que cuando se ejecuta el SP, si miro los bloqueos en el
Entreprise Manager, las tablas que participan en el SP aparacen con
un bloqueo X, que creo que quiere decir exclusivo, por lo que los
otros procesos no tiene acceso, ¿no?




"Javier Loria" escribió en el mensaje
news:
Hola Victor:
Si agregas el nivel de Insolation Serializabe lograras lo
deseado pero es casi seguro que sea un exceso que deteriorara el
desempeno de la apliacion. Depende de como generas el ultimo numero
de factura. Actualmente (sin el cambio) cuando lees el ultimo
numero y le sumas uno, no es suficiente hacer BEGIN TRAN/COMMIT ya
que no bloqueas el registro. Por esto es posible que alguien mas
lea la factura casi simultaneamente (antes de hacer el commit)
realice
la misma suma de 1 y tendras 2 facturas iguales!!!.
El usar un nivel SERIALIZABLE parace demasiado "fuerte" como
solucion, basicamente NADIE podra hacer ninguna modificacion
ninguna de las tablas y quedaran en espera que termine la
transaccion. Lo
cual puede hacer bastante mas lento el sistema. Aun cuando
finalmente se va a requerir en alguna parte un bloqueo, debes
disenarlo de forma tal que quede lo "minimo necesario" bloqueado y
no TODAS las tablas que participan. Saludos,


Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.

Víctor escribio:
Hola a

Al ejecutarse un SP que tengo, lo primero que hace es leer los
campos de una tabla (A).
Luego empieza a leer campos de otras tablas y realizar inserts, y
por último actualiza la tabla (A).

Necesito que desde que lee A hasta que lo actualiza, nadie pueda
acceder a esta tabla (bueno, al menos a la fila que el SP ha
leido), pues esta tabla la utilizo como contador de facturas.

Lo que hice era primero de todo poner BEGIN TRAN, y al final un
COMMIT TRAN, y por en medio, si algo fallaba, un ROLLBACK TRAN.

Y hasta ahora (4 añitos) todo ha ido perfecto, pero la semana
pasada se me repitieron dos números de facturas :-(

No se qué ha podido pasar.

Ahora he puesto, antes del BEGIN TRAN, un SET TRANSACTION
ISOLATION LEVEL SERIALIZABLE.

¿Me servirá para algo o con el BEGIN TRAN ya me hes suficiente y
el problema es otro?

Muchas gracias.
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una pregunta AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida