2009-10-02 9 views
13

J'ai un grand rapport que je courais sur le serveur SQL. Cela prend plusieurs minutes à courir. Je ne veux pas que les utilisateurs cliquent deux fois. Puisque je recouvre toute la procédure dans une transaction, comment puis-je vérifier si la table est verrouillée par une transaction? Si oui, je voudrais retourner un message d'erreur disant "génération de rapports, s'il vous plaît essayer à nouveau dans quelques minutes".Comment vérifier si une table est verrouillée dans le serveur SQL

Comment cela peut-il être accompli?

Répondre

9

Mieux encore, pensez sp_getapplock qui est conçu pour cela. Ou utilisez SET LOCK_TIMEOUT

Sinon, vous devrez faire quelque chose avec sys.dm_tran_locks que je n'utiliserais que pour les choses DBA: pas pour la concurrence définie par l'utilisateur.

+0

SET LOCK_TIMEOUT est la meilleure solution –

+4

ne définit le travail LOCK_TIMEOUT si NOLOCK est ...? – gbn

16

Vous pouvez utiliser la vue sys.dm_tran_locks, qui renvoie des informations sur les ressources du gestionnaire de verrous actuellement actifs.

Essayez cette

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 vous vérifiez si un verrou est appliqué sur une table ou non, essayez de la requête ci-dessous.

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 contient les informations de verrouillage des sessions

Si vous voulez savoir une table spécifique est verrouillé ou non, vous pouvez utiliser la requête suivante

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

si vous êtes intéressé à trouver à la fois le nom de connexion de l'utilisateur et la requête en cours d'exécution

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' 

Pour plus infomraton locking query

Plus infor à propos sys.dm_tran_locks

Questions connexes