2009-10-02 14 views
13

Tengo un informe grande que estoy ejecutando en el servidor sql. Tarda varios minutos en ejecutarse. No quiero que los usuarios hagan clic dos veces. Dado que envuelvo todo el procedimiento en una transacción, ¿cómo puedo verificar si la tabla está bloqueada por una transacción? Si es así, me gustaría devolver un mensaje de error que diga "generación de informes, inténtelo de nuevo en unos minutos".Cómo comprobar si una tabla está bloqueada en el servidor sql

¿Cómo se puede lograr esto?

Respuesta

9

Mejor aún, considere sp_getapplock que está diseñado para esto. O use SET LOCK_TIMEOUT

De lo contrario, tendría que hacer algo con sys.dm_tran_locks que usaría solo para DBA: no para concurrencia definida por el usuario.

+0

LOCK_TIMEOUT SET es la mejor solución –

+4

sí establece el trabajo LOCK_TIMEOUT si se utiliza NOLOCK ...? – gbn

16

Puede usar la vista sys.dm_tran_locks, que devuelve información sobre los recursos del administrador de bloqueos actualmente activos.

probar este

SELECT 
    SessionID = s.Session_id, 
    resource_type, 
    DatabaseName = DB_NAME(resource_database_id), 
    request_mode, 
    request_type, 
    login_time, 
    host_name, 
    program_name, 
    client_interface_name, 
    login_name, 
    nt_domain, 
    nt_user_name, 
    s.status, 
    last_request_start_time, 
    last_request_end_time, 
    s.logical_reads, 
    s.reads, 
    request_status, 
    request_owner_type, 
    objectid, 
    dbid, 
    a.number, 
    a.encrypted , 
    a.blocking_session_id, 
    a.text  
FROM 
    sys.dm_tran_locks l 
    JOIN sys.dm_exec_sessions s ON l.request_session_id = s.session_id 
    LEFT JOIN 
    (
     SELECT * 
     FROM sys.dm_exec_requests r 
     CROSS APPLY sys.dm_exec_sql_text(sql_handle) 
    ) a ON s.session_id = a.session_id 
WHERE 
    s.session_id > 50 
5

Si usted está verificando si se aplica un bloqueo en una mesa o no, pruebe la consulta a continuación.

SELECT resource_type, resource_associated_entity_id, 
    request_status, request_mode,request_session_id, 
    resource_description, o.object_id, o.name, o.type_desc 
FROM sys.dm_tran_locks l, sys.objects o 
WHERE l.resource_associated_entity_id = o.object_id 
    and resource_database_id = DB_ID() 
2

sys.dm_tran_locks contiene la información de bloqueo de las sesiones

Si quieres conocer una tabla específica está bloqueado o no, puede utilizar la siguiente consulta

SELECT 
* 
from 
sys.dm_tran_locks 
where 
    resource_associated_entity_id = object_id('schemaname.tablename') 

si Está interesado en encontrar el nombre de usuario y la consulta que se está ejecutando

SELECT 
DB_NAME(resource_database_id) 
, s.original_login_name 
, s.status 
, s.program_name 
, s.host_name 
, (select text from sys.dm_exec_sql_text(exrequests.sql_handle)) 
,* 
from 
    sys.dm_tran_locks dbl 
    JOIN sys.dm_exec_sessions s ON dbl.request_session_id = s.session_id 
    INNER JOIN sys.dm_exec_requests exrequests on dbl.request_session_id = exrequests.session_id 
where 
DB_NAME(dbl.resource_database_id) = 'dbname' 

Para más infomraton locking query

Más infor sobre sys.dm_tran_locks

Cuestiones relacionadas