Problemas con los bloqueos en la base de datos

22/12/2003 - 11:13 por dcanete | Informe spam
Tengo un problema de bloqueos que me tiene frito. A ver si a alguien
se le ocurre alguna solucion.

Ejecuto la siguiente sentencia en una conexion desde el analizador de
consultas:
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
begin tran
SELECT VinculacionesProyectos.idVinculacionProyecto,
VinculacionesProyectos.idUsuarioModificacion
FROM AplicacionesPresupuestarias INNER JOIN
VinculacionesProyectos ON
AplicacionesPresupuestarias.idAplicacionPresupuestaria VinculacionesProyectos.idAplicacionPresupuestaria
WHERE (AplicacionesPresupuestarias.idAplicacionJuridica = 2)


Y despues la siguiente en otra conexion:
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
begin tran
UPDATE VinculacionesProyectos
SET VinculacionesProyectos.fModificacion = getdate()
WHERE VinculacionesProyectos.idVinculacionProyecto = 33
rollback

Hasta que no termina la primera no ejecuta la segunda. Más datos por
si os sirve de pista:
* La primera consulta devuelve datos de las filas distintas a la que
se pretende modificar en la segunda consulta.
* Si cambio el isolation level a read committed en la segunda, sigue
igual
* Si cambio el isolation level a read committed en la primera,
funciona
* Existen índices para las siguientes columnas:
VinculacionesProyectos.idVinculacionProyecto (clustered)
VinculacionesProyectos.idProyecto,
VinculacionesProyectos.idAplicacionPresupuestaria
AplicacionesPresupuestarias.idAplicacionPresupuestaria
* El optimizador de consultas usa el primer y el último indice de
los arriba indicado
* Mi direccion por si acaso: dcanete@sadiel.es

Si necesitais más datos no teneis más que preguntarme.

Gracias por anticipado.

Preguntas similare

Leer las respuestas

#1 Miguel Egea
22/12/2003 - 12:36 | Informe spam
Buenas, lo que puede suceder es que por el volumen de registros afectados
la graunularidad del bloqueo no sea registro sino de página, puedes
comprobar eso revisando la tabla master..sysproceses o mejor la tabla
syslockinfo, la granularidad te la da este campo
rsc_type tinyint Tipo de recurso. Puede ser:
1 = Recurso NULL (no utilizado).
2 = Base de datos.
3 = Archivo.
4 = Índice.
5 = Tabla.
6 = Página.
7 = Clave.
8 = Extensión.
9 = RID (Id. de fila).
10 = Aplicación



En cuanto uno solo de los registros esté afecatdo toda la sentencia se queda
esperando. Por otra parte la solución la tienes tú, si eso es un problema
baja el nivel de aislamiento del select a READ COMMITTED, básicamente así
puede suceder lecturas fantasmas y lecturas no repetibles, es decir que dos
select iguales dentro de la misma transaccion ofrezcan datos distintos si
entre uno y el otro se produce un update. No se si esto es aceptable en tu
sistema, si lo és, no veo el motivo para no cambiarlo ganarás mucho en
concurrencia.

Si el problema es bloqueos de página se puede solucionar (o nó) con más
memoria en el servidor.

Saludos
Miguel Egea

"Daniel Ca?ete" escribió en el mensaje
news:
Mostrar la cita
#2 dcanete
23/12/2003 - 09:52 | Informe spam
Ante todo, gracias por tu interes.

El nivel de aislamiento no se puede cambiar por necesidades del
sistema.

He revisado la granularidad y es a nivel de fila, pero creo que
bloquea todas las filas existentes de la tabla VinculacionesProyectos.
En la tabla VinculacionesProyectos hay 238 registros que son los
bloqueos de fila que hay para el spid correspondiente, cuando en
realidad devuelve datos de solo tres registros.

Creo que el problema está en como realiza la consulta el optimizador:
filtra la tabla AplicacionesPresupuestarias según el where y en
paralelo toma todos los registros de la tabla VinculacionesProyectos.
Posteriormente hace el join entre las dos tablas.

Tengo entendido que con REPEATABLE READ bloquea todo lo que usa, no
solo lo que devuelve, por eso pienso que la solucion esta en decirle
de alguna manera al optimizador de consultas que haga la consulta de
esta manera:
SELECT VinculacionesProyectos.idVinculacionProyecto,
VinculacionesProyectos.idUsuarioModificacion
FROM VinculacionesProyectos
where idAplicacionPresupuestaria in (
select idAplicacionPresupuestaria
from AplicacionesPresupuestarias
WHERE (AplicacionesPresupuestarias.idAplicacionJuridica = 2)
)

Escribiendola así, sigue pasando lo mismo y el plan de ejecucion es
exactamente igual. ¿Hay alguna manera de obligar a hacerlo de esta
manera?

Un saludo y FELICES FIESTAS a todos


"Miguel Egea" wrote in message news:<#Pqwh$...
Mostrar la cita
#3 dcanete
24/12/2003 - 10:01 | Informe spam
Sigo teniendo el problema. Ayuda por favor!!

(Daniel Ca?ete) wrote in message news:...
Mostrar la cita
#4 Miguel Egea
29/12/2003 - 14:07 | Informe spam
Buenas, puedes cambiar el modo de bloqueo solo para esta tabla con un hint
with(READCOMMITTED) creo recordar, así no tendrásx problemas, otra opción es
forzar a sql a usar un índice concreto sobre esa tabla, de todas formas si
es estática esa tabla, el nivel de aislamiento en esa tabla concreta no
debiera tener mayor problema.
Puedes sin embargo usar una funcion de tipo tabla para que devuelva solo los
registros de esa tabla a través del índice que tu consideres oportuno, así
en lugar de bloquear la tabla solo bloquearas los afectados, sin tener que
cambiar mucho tu código.

Saludos
Miguel Egea


"Daniel Ca?ete" escribió en el mensaje
news:
Mostrar la cita
news:...
Mostrar la cita
news:<#Pqwh$...
Mostrar la cita
afectados
Mostrar la cita
queda
Mostrar la cita
problema
Mostrar la cita
así
Mostrar la cita
que dos
Mostrar la cita
si
Mostrar la cita
en tu
Mostrar la cita
más
Mostrar la cita
de
Mostrar la cita
que
Mostrar la cita
sigue
Mostrar la cita
Ads by Google
Search Busqueda sugerida