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

#1 Javier Loria
25/04/2004 - 11:47 | Informe spam
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.
Respuesta Responder a este mensaje
#2 Víctor
25/04/2004 - 13:02 | Informe spam
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.


Respuesta Responder a este mensaje
#3 Javier Loria
25/04/2004 - 14:13 | Informe spam
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.
Respuesta Responder a este mensaje
#4 Víctor
25/04/2004 - 22:16 | Informe spam
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.


Respuesta Responder a este mensaje
#5 Jose Mariano Alvarez \(MUG\)
26/04/2004 - 07:16 | Informe spam
Si el primer paso es el update de la tabla contadores, y eso esta dentro de
la transacción entonces ya queda bloqueado. Luego si precisas puedes hacer
el select y sabes que no lo va a cambiar otro proceso.


Jose Mariano Alvarez
Comunidad de base de datos
Grupo de Usuarios Microsoft
www.mug.org.ar


"Víctor" wrote in message
news:O0Vic.4708281$
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.
>
>







Revisado por AVG

Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.668 / Virus Database: 430 - Release Date: 24/04/2004
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida