viernes, 1 de marzo de 2013

Solucionar Bloqueos en Tablas SQL Server


Resulta que cuando una tabla es muy utilizada (muchas consultas), o cuando se “cruzan” las transacciones sobre la misma tabla, se produce un bloqueo a nivel de tabla, lo que hace que ya no se puedan realizar más consultas. 
Según lo que leí (inicialmente en blog.andr3z.org y luego en otros lugares), existen 2 posibles soluciones al problema:
  •  Modificar la consulta para saltarnos el bloqueo
  • Intentar resolver el bloqueo de la tabla

Cada solución tiene su propio alcance, sus pros y contras, veamos cada solución en detalle:

  • Solución 1: Modificar la consulta para “saltar” el bloqueo:


    Ámbito: No se desbloquea la tabla, solo se devuelven los resultados

    Pros: Permite realizar el SELECT sin restricción.

Contras: Puede retornar resultados fuera del Committed de la base de datos (es decir que los resultados pueden no ser fidedignos)

Para implementar esta solución, basta modificar el SELECT de la consulta, agregando el modificador WITH (NOLOCK), lo que hará que se omita el bloqueo de la tabla:

SELECT Field1, Field2,… FieldN FROM [Mi_Tabla] WITH (NOLOCK) WHERE …

  • Solución 2: Intentar resolver el bloqueo de la tabla:

    Ámbito: Se intenta resolver el bloqueo.
Pros: Se resuelve definitivamente el bloqueo (por lo menos hasta que se vuelva a producir un bloqueo nuevo en la misma tabla)

    Contras: Requiere tener acceso/permisos para “Matar” procesos (incluso de otros usuarios).

Para esta solución, SQL server provee un procedimiento almacenado que muestra los bloqueos en curso: sp_lock.

Basta con ejecutar:

Execute sp_lock

Para ver los bloqueos activos en la base de datos.

Cabe mencionar que adicionalmente SQL Server también provee 2 procedimientos que permiten listar los procesos que están consumiendo muchos recursos: sp_who o sp_who2 siendo este último el que provee más detalles.

Una vez se ha identificado cual es el proceso que esta provocando el bloqueo, se puede proceder a “Matar” dicho proceso utilizando la información que arrojan los procedimientos ya mencionados (básicamente se requiere el ID del proceso que se va a matar).

Ejecutar: 

Kill <id_del_proceso_a_matar>

Bueno, pues eso era todo, como siempre, espero que esta información llegue a ser útil para alguno de ustedes.

Fuente: eklectopia

No hay comentarios: